Java入门首周精要:从基础语法到面向对象核心解析
文章目录
- Java入门首周精要:从基础语法到面向对象核心解析
- 1.Java类名与文件名的一致性规则
- 2.Java和C语言中char类型的区别
- 3.Java中的注释
- 4.Java中的‘’+‘’运算符
- 5.Java的输入输出
- 6.方法(重载&重写)
- 方法的重载
- 方法的重写
- 7.面向对象(OOP) VS 面向过程(POP)
- 8.类(Class)和对象(Object)
- 9.成员变量 VS 局部变量
- 10.构造方法(构造器)
- 11.JavaBean是什么?
- 12.static关键字
- 13.继承
- 14.this和super关键字
- 15.抽象类 VS 接口
- 16.多态
- 17.权限修饰符
- 18.final关键字
- 19.构造代码块 VS 静态代码块
- 20.内部类
- 21.异常
- 22.为什么String类可以不用new创建对象?
- 23.增强for
Java入门首周精要:从基础语法到面向对象核心解析
1.Java类名与文件名的一致性规则
规则:
- 如果一个类被声明为
public
,那么文件名必须与该类的名称完全一致(包括大小写)。- 一个
.java
文件中只能有一个public
类,但可以有多个非public
类。- 如果没有
public
类,文件名可以任意(但通常与主类名一致)。Java的设计逻辑:
- Java强制要求
public
类名与文件名一致,是为了让编译器能快速定位类。Java的每个类在编译后都会生成独立的.class
文件(如Car.class
、Engine.class
)。public
类可以被其他包中的代码访问,因此需要明确的文件名与类名对应关系,确保JVM在加载类时能找到正确的文件。建议:
- 始终让文件名与
public
类名一致:避免编译错误。- 一个文件只放一个类:提高代码可读性(即使允许放多个类)。
- 注意大小写:Java区分大小写,
Car.java
和car.java
是不同的文件!
2.Java和C语言中char类型的区别
C语言:
- C语言中
char
类型通常为8位(1字节),采用ASCII或本地扩展编码,取值范围通常是 0 − 255 0-255 0−255(无符号char
)或 − 128 − 127 -128-127 −128−127(有符号char
),符号默认由编译器决定,可显式声明有无符号。
- 仅能表示256种可能的值,无法直接处理Unicode字符。
- 多字节字符(如中文)需依赖外部库(如
wchar_t
或UTF-8编码的函数)。Java:
而Java中的
char
类型固定为16位(2字节),采用Unicode编码(UTF-16),始终是无符号的,取值范围是\u0000
(0)~\uffff
(65535)
\u
用于表示 Unicode 字符的转义序列,格式为\uXXXX
,其中XXXX
是 4 位 16 进制数,对应 Unicode 码点的值(C 语言默认不支持)。\u
作为字符转义序列,但在 C11 及之后的标准 中,引入了\u
作为 Unicode 字符转义码点是什么?
码点(Code Point) 是 Unicode 字符集中的 唯一数字标识符,用来表示一个字符。Unicode 码点的范围是 从
U+0000
到U+10FFFF
,其中:
U+
表示 Unicode 码点的前缀。0000
~10FFFF
是 十六进制 数,表示 Unicode 字符的索引。UTF-16编码是一种变长编码,大部分常用字符(BMP平面,即
U+0000
到U+FFFF
)用1个char
表示。超出BMP的字符(如部分Emoji,U+10000
到U+10FFFF
)需要用2个char
(代理对)表示。
什么是BMP?
BMP,全称为 Basic Multilingual Plane,中文意为基本多文种平面。Unicode 共有
17
个平面,BMP 是 Unicode 的0
号平面,即[U+0000, U+FFFF]
区间。BMP 包含了几乎所有的现代语言的文字和大量的符号。总结:
- C的
char
:
面向底层,直接操作字节,符号性灵活,适合处理原始数据或ASCII文本,但需手动处理编码和多字节字符。- Java的
char
:
为国际化设计,强制使用UTF-16编码,无符号且类型安全,适合处理多语言文本,但灵活性较低。
3.Java中的注释
单行注释:
//
多行注释:
/* ... */
文档注释:
/** ... */
在Java中,文档注释(Javadoc) 是一种特殊的注释格式,用于生成标准的API文档(HTML格式),方便开发者理解类、方法、字段的功能和使用方式。
语法格式:
/*** 描述内容* @标签名 标签内容*/
- 以
/**
开头,*/
结尾。- 每行以
*
开头(非强制,但建议对齐以增强可读性)。核心Javadoc标签:
标签 用途 示例 @param
描述方法的参数(仅用于方法) @param num1 第一个整数
@return
描述方法的返回值(非 void
方法必须使用)@return 两个整数的和
@throws
/@exception
描述方法可能抛出的异常 @throws IllegalArgumentException 参数为负数时抛出
@deprecated
标记方法或类已过时,建议使用替代方案 @deprecated 使用 {@link #newMethod()} 代替
@see
添加相关类、方法或资源的参考链接 @see java.util.ArrayList
@since
指定引入该功能的版本 @since 1.8
@author
标注作者(通常用于类或接口) @author John Doe
@version
指定版本号(通常用于类或接口) @version 1.0.0
{@link}
内联链接到其他类或方法 使用 {@link #calculateSum(int, int)} 计算和
{@code}
将内容格式化为代码样式(不解析HTML) {@code int x = 5;}
用法示例:
类注释:
/*** 表示一个二维坐标系中的点。* * @author Jane Smith* @version 1.2* @since 1.0*/ public class Point {private int x;private int y;// ... }
方法注释:
/*** 计算两个整数的和。* * @param num1 第一个加数(必须为非负数)* @param num2 第二个加数* @return 两个参数的和* @throws IllegalArgumentException 如果num1为负数* @see <a href="http://example.com">算法参考文档</a>*/ public int add(int num1, int num2) {if (num1 < 0) {throw new IllegalArgumentException("num1不能为负数");}return num1 + num2; }
生成Javadoc文档:
命令行生成:
javadoc -d docs -encoding UTF-8 -charset UTF-8 MyClass.java
-d docs
:指定输出目录为docs
。-encoding UTF-8
:指定源文件编码。-charset UTF-8
:指定生成文档的字符集。IDE生成:
Tools
→Generate JavaDoc
→ 配置输出目录和选项 → 点击生成。核心价值:
生成标准化API文档,提升代码可维护性和团队协作效率。
4.Java中的‘’+‘’运算符
在Java中,
+
运算符是一个多功能操作符,主要用于算术加法和字符串连接
算术加法:
适用场景:操作数均为数值类型(
byte
,short
,int
,long
,float
,double
,char
)。规则:
- 若操作数类型不同,会进行隐式类型提升(向更高精度的类型转换)。
- 运算结果类型与提升后的类型一致。
示例:
int a = 5 + 3; // 8(int + int → int) double b = 5 + 3.0; // 8.0(int + double → double) char c = 'A' + 1; // 'B'(char提升为int,计算后转回char)
字符串拼接:
适用场景:任一操作数为字符串(
String
)类型。规则:
- 非字符串操作数会自动转换为字符串(调用
toString()
方法)。- 运算结果为新的字符串对象。
示例:
String s1 = "Hello" + " World"; // "Hello World" String s2 = "Age: " + 25; // "Age: 25"(int转String) String s3 = 10 + 20 + "30"; // "3030"(先计算10+20=30,再连接"30") String s4 = "Sum: " + (10 + 20); // "Sum: 30"(括号改变优先级)
在 Java 中,字符串是不可变的,每次使用
+
连接字符串时,实际上是创建了一个新的String
对象。为了提高性能,Java 提供了StringBuilder
和StringBuffer
来优化字符串的连接操作。StringBuilder sb = new StringBuilder(); sb.append("Hello").append(" ").append("World"); String result = sb.toString(); // "Hello World"
5.Java的输入输出
控制台输出:
System.out
:标准输出流,默认输出到控制台。
System.out.print()
:输出不换行。System.out.println()
:输出并换行。System.out.printf()
:格式化输出(类似C语言)。System.out.print("Hello"); // Hello System.out.println(" World"); // World(换行) System.out.printf("PI: %.2f", Math.PI); // PI: 3.14
控制台输入:
Scanner
类:最常用的输入工具,可解析基本类型和字符串。import java.util.Scanner; // 导包public class ConsoleInput {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("请输入姓名: ");String name = scanner.nextLine(); // 读取整行输入System.out.print("请输入年龄: ");int age = scanner.nextInt(); // 读取整数System.out.printf("姓名: %s, 年龄: %d", name, age);} }
- 常用方法:
nextInt()
、nextDouble()
:读取数值。nextLine()
:读取整行(包括空格)。next()
:读取单词(以空格分隔)。
6.方法(重载&重写)
定义:
方法是类或对象中用于执行特定任务的代码块。它接受输入参数(可选),执行操作,并可能返回结果。方法封装了功能,提高了代码的可重用性和模块化。
语法:
访问修饰符 返回类型 方法名(参数列表) {// 方法体 }
- 访问修饰符:如
public
、private
、protected
,控制方法的可见性。- 返回类型:方法返回值的数据类型,无返回值时用
void
。- 参数列表:传递给方法的参数,可为空。
- 方法体:实现具体逻辑的代码块。
示例:
public int add(int a, int b) {return a + b; }
方法的重载
定义:
在同一个类中定义多个同名方法,但它们的参数列表不同(参数类型、个数或顺序不同)。返回类型可以不同,但仅返回类型不同不足以构成重载。
- 方法名必须相同。
- 参数列表必须不同(类型、数量或顺序)。
- 返回类型、访问修饰符和异常声明可以不同。
作用:
提高代码可读性,允许用同一方法名处理不同类型或数量的参数。
示例:
public class Calculator {// 重载1:两个int参数public int add(int a, int b) {return a + b;}// 重载2:三个int参数public int add(int a, int b, int c) {return a + b + c;}// 重载3:double类型参数public double add(double a, double b) {return a + b;} }
calc.add(2, 3); // 调用重载1 calc.add(1, 2, 3); // 调用重载2 calc.add(1.5, 2.5); // 调用重载3
方法的重写
定义:
子类重新定义父类中已有的方法,以提供特定实现。重写是实现运行时多态的关键。
- 方法名、参数列表和返回类型必须与父类方法一致(Java 5+ 允许返回子类类型)。
- 访问修饰符不能比父类更严格(如父类是
protected
,子类可为public
,但不能为private
)。- 子类方法抛出的异常不能比父类更宽泛。
- 不能重写
static
、final
或private
方法。作用:
允许子类自定义行为,实现多态性。
示例:
class Animal {public void sound() {System.out.println("动物发出声音");} }class Dog extends Animal {@Overridepublic void sound() {System.out.println("汪汪");} }class Cat extends Animal {@Overridepublic void sound() {System.out.println("喵喵");} }
Animal myDog = new Dog(); myDog.sound(); // 输出 "汪汪"(多态)
注:
@Override
是 Java 中的一个注解(Annotation),用于明确标识某个方法是重写(Override)了父类或接口中的方法。它的核心作用是让编译器帮助你检查方法重写的正确性,避免因拼写错误、参数不匹配等问题导致重写失败。作用:
编译时检查
如果使用了@Override
注解,编译器会强制检查该方法是否:
- 确实重写了父类或接口中的方法。
- 方法名、参数列表、返回类型与父类完全一致。
- 访问权限符不低于父类方法(例如,父类方法是
protected
,子类不能是private
)。如果不符合重写规则,编译器会直接报错,而不是默默接受错误代码。
提高代码可读性
明确告诉其他开发者这是一个重写方法,增强代码的可维护性。
7.面向对象(OOP) VS 面向过程(POP)
之前学过的C语言是典型的面向过程编程语言,而现在正在学的Java是面向对象编程语言的代表。
什么是面向过程编程?
定义:
面向过程编程是一种以**过程(函数)**为核心的编程范式,通过将程序分解为一系列线性步骤(函数调用),逐步操作数据以完成任务。其核心思想是“怎么做”(How to do)。
核心特征:
- 函数为中心:程序由函数构成,每个函数实现特定功能。
- 数据与行为分离:数据(变量)独立于函数,函数通过参数接收数据并处理。
- 线性流程:代码按预定义顺序执行,强调算法和逻辑步骤。
- 典型语言:C、Pascal、Fortran。
优缺点:
优点 缺点 简单直观,适合小型程序 代码复用性差 执行效率高 难以管理复杂系统 适合算法密集型任务 数据与行为分离易导致耦合度高 什么是面向对象编程?
定义:
面向对象编程是一种以对象为核心的编程范式,将现实世界的实体抽象为包含数据(属性)和行为(方法)的对象,并通过封装、继承、多态、抽象四大特性构建程序。其核心思想是“谁来做”(Who does what)。
核心特征:
- 对象为中心:程序由对象组成,对象是类的实例。
- 封装性:将数据和方法绑定,隐藏内部实现细节。
- 继承性:子类复用父类的属性和方法。
- 多态性:同一接口在不同对象中有不同实现。
- 典型语言:Java、C++、Python。
优缺点:
优点 缺点 代码模块化,易维护扩展 学习曲线陡峭 支持代码复用(继承/组合) 性能略低于面向过程 适合复杂系统开发 过度设计可能导致冗余 核心对比:
面向过程 面向对象 核心单位 函数 对象 设计目标 步骤分解 职责划分 数据与行为 分离 绑定(封装) 扩展性 低(需修改函数) 高(继承、多态) 适用场景 小型工具、算法、嵌入式开发 大型系统、GUI、企业级应用 叽里咕噜的说什么呢,想象你要做一道菜(比如番茄炒蛋),面向过程就是:你亲自动手,严格按照步骤一步一步来:
1. 洗番茄 → 2. 切番茄 → 3. 打鸡蛋 → 4. 开火 → 5. 炒菜 → 6. 出锅
关注的是步骤(先干什么,后干什么),所有事情都要自己干,没有分工,假如你还要做另一道菜(比如青椒肉丝),你需要重写一遍所有步骤。
想象你开了一家餐厅,面向对象就是:你把任务分给不同的人(对象),比如:
- 厨师对象:负责做菜 - 服务员对象:负责端菜 - 收银员对象:负责收钱
关注的是谁来做(每个对象只负责自己的任务),不同对象之间互相配合(比如服务员告诉厨师做菜),如果要新增一道菜,只需要让厨师学新菜谱,其他岗位不用变。
- 面向过程 ➜ “自己做所有事”(关注步骤)。
- 面向对象 ➜ “让别人帮你做事”(关注分工)。
为什么要有面向对象?
想象你开的是大型连锁餐厅:
- 如果每道菜都自己从头做到尾(面向过程),会累死,而且难以管理。
- 如果用面向对象的方式,每个岗位各司其职,系统更灵活,容易扩展(比如新增一个配送员送外卖)。
8.类(Class)和对象(Object)
类(Class):
定义:
- 类 是一个模板或蓝图,用于描述一类对象的属性(成员变量)和行为(成员方法)。
- 类定义了对象的类型,但本身不占用内存空间,只有通过
new
关键字创建对象时才会分配内存。语法:
public class 类名 {// 成员变量(属性)数据类型 变量名;// 构造方法(初始化对象)public 类名(参数列表) {// 初始化代码}// 普通方法(行为)返回类型 方法名(参数列表) {// 方法体} }
示例:
public class Car {// 成员变量(属性)String color;String brand;// 构造方法public Car(String color, String brand) {this.color = color;this.brand = brand;}// 方法(行为)public void start() {System.out.println(brand + "汽车启动了!");} }
对象(Object):
定义:
- 对象 是类的一个具体实例,通过
new
关键字创建。- 每个对象在内存中独立存在,拥有自己的成员变量值(数据)和方法实现(行为)。
如何创建对象?
使用
new
关键字:
- 分配内存:在堆内存中为对象分配空间。
- 调用构造方法:初始化对象的成员变量。
- 返回引用:将对象的内存地址赋给变量(引用)。
语法:
类名 对象名 = new 类名(参数列表);
示例:
public class Main {public static void main(String[] args) {// 创建 Car 类的对象Car myCar = new Car("红色", "Toyota");Car yourCar = new Car("蓝色", "BMW");// 调用对象的方法myCar.start(); // 输出:Toyota汽车启动了!yourCar.start(); // 输出:BMW汽车启动了!} }
9.成员变量 VS 局部变量
成员变量:
定义:
- 定义在类内部,但在方法、构造方法或代码块之外。
- 包括两种类型:
- 实例变量(非静态成员变量)
- 类变量(静态成员变量,用
static
修饰)特点:
- 作用域:
- 整个类内部均可访问。
- 实例变量通过对象访问(
obj.variable
),静态变量通过类名访问(Class.variable
)。- 生命周期:
- 实例变量:随对象创建而存在,对象被垃圾回收时销毁。
- 静态变量:随类加载而存在,程序结束时销毁。
- 默认值:
- 成员变量有默认初始值(如
int
默认为0
,对象类型默认为null
)。- 存储位置:
- 实例变量:存储在堆内存(对象内部)。
- 静态变量:存储在方法区(类元数据区)。
示例:
public class Car {// 实例变量(成员变量)private String brand; // 默认值为 nullprivate int speed; // 默认值为 0// 静态变量(类变量)public static int wheels = 4; // 显式初始化public void accelerate() {speed += 10; // 可以直接访问成员变量} }
局部变量:
定义:
定义在方法、构造方法、代码块内部或形参列表中。
特点:
- 作用域:
- 仅在定义它的方法、代码块内部有效。
- 超出作用域后无法访问。
- 生命周期:
- 随方法/代码块的执行而创建,执行结束后销毁。
- 默认值:
- 没有默认值,必须显式初始化后才能使用。
- 存储位置:
- 存储在栈内存(方法调用栈帧中)。
示例:
public class Calculator {public int add(int a, int b) { // 形参 a、b 是局部变量int result = a + b; // 局部变量 resultreturn result; // result 的作用域仅在 add 方法内}public void printSum() {int x = 5; // 局部变量 xint y = 10;System.out.println(x + y); // 正确System.out.println(result); // 错误!result 在此不可见} }
核心对比:
特性 成员变量 局部变量 定义位置 类内部,方法外 方法、代码块内部或形参列表 作用域 整个类内部 仅方法/代码块内部 生命周期 对象或类存在期间 方法/代码块执行期间 默认值 有默认值(如 0
/null
)必须显式初始化 存储位置 堆(实例变量)或方法区(静态) 栈 访问权限 可添加访问修饰符(如 public
)不能使用访问修饰符 内存分配 自动分配 需要手动初始化 局部变量和成员变量同名时怎么办?
局部变量会覆盖成员变量(就近原则),通过
this
关键字访问成员变量。public class Test {private int value = 10;public void setValue(int value) {this.value = value; // this.value 是成员变量,value 是局部变量} }
10.构造方法(构造器)
在 Java 中,构造方法(Constructor)是类中用于初始化对象的特殊方法,在对象创建时自动调用。
核心特性:
命名与类名相同
构造方法必须与类名完全一致(包括大小写)。无返回类型
构造方法没有返回值(连void
也不写),例如:public class Student {// 构造方法(无返回类型)public Student() { ... } }
自动触发
通过new
关键字创建对象时,构造方法自动执行。可重载
一个类可以有多个构造方法(参数不同),提供多种初始化方式。分类:
默认构造方法(无参构造方法)
如果类中未显式定义任何构造方法,Java 编译器会自动生成一个默认的无参构造方法。
示例:
public class Student {// 编译器自动生成默认构造方法:public Student() {} }
自定义构造方法(带参数):
开发者显式定义,用于灵活初始化对象属性。
示例:
public class Student {private String name;private int age;// 自定义构造方法public Student(String name, int age) {this.name = name;this.age = age;} }
基本用法:
public class Student {private String name;private int age;// 无参构造方法(显式定义)public Student() {}// 有参构造方法public Student(String name, int age) {this.name = name;this.age = age;}public static void main(String[] args) {Student stu1 = new Student(); // 调用无参构造方法Student stu2 = new Student("张三", 18); // 调用有参构造方法} }
构造方法的重载:
public class Car {private String brand;private String color;// 构造方法1:仅初始化品牌public Car(String brand) {this.brand = brand;this.color = "黑色";}// 构造方法2:初始化品牌和颜色public Car(String brand, String color) {this.brand = brand;this.color = color;} }
构造方法(构造器) 是对象创建的入口,用于确保对象初始状态合法。通过重载构造方法,可以提供多种初始化方式。
11.JavaBean是什么?
定义:JavaBean 是一种符合特定编码规范的 Java 类,主要用于封装数据和提供标准化操作。
核心规范:
公共的无参构造方法
类必须提供无参数构造方法,以便通过反射机制实例化对象。
示例:
public class User {public User() {} // 必须有无参构造方法 }
属性私有化
所有属性(字段)必须声明为
private
,禁止直接暴露给外部。private String name; private int age;
通过公共方法访问属性
提供
getXxx()
和setXxx()
方法操作属性(称为 Getter 和 Setter)。布尔类型属性可使用
isXxx()
作为 Getter。public String getName() {return name; } public void setName(String name) {this.name = name; }
示例:
public class User {// 属性私有化private String name;private int age;private boolean active;// 无参构造方法(必须)public User() {}// 带参构造方法(可选)public User(String name, int age) {this.name = name;this.age = age;}// Getter 和 Setter(必须)public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}// 布尔类型可使用 isXxx()public boolean isActive() {return active;}public void setActive(boolean active) {this.active = active;} }
12.static关键字
static
是 Java 中用于修饰类成员(变量、方法、代码块、内部类)的关键字,表示该成员属于类本身而非类的实例。其主要目的是实现与类直接关联的功能或数据共享,避免重复创建实例的消耗。应用场景:
静态变量(类变量)、
定义:用
static
修饰的成员变量,属于类而非实例。特点:
- 所有实例共享同一份静态变量。
- 内存中仅在类加载时分配一次(存储在方法区/元空间)。
- 可通过
类名.变量名
直接访问,无需实例化对象。示例:
public class Counter {static int count = 0; // 静态变量public Counter() {count++; // 所有实例共享 count}public static void main(String[] args) {new Counter();new Counter();System.out.println(Counter.count); // 输出 2} }
静态方法
定义:用
static
修饰的方法,属于类而非实例。特点:
- 只能直接访问静态成员(变量/方法),不能访问实例成员。
- 可通过
类名.方法名()
直接调用。- 常用作工具方法(如
Math.sqrt()
)。示例:
public class MathUtils {public static int add(int a, int b) { // 静态方法return a + b;}public static void main(String[] args) {int result = MathUtils.add(3, 5); // 直接调用System.out.println(result); // 输出 8} }
静态代码块
定义:用
static { ... }
定义的代码块,在类加载时执行一次。用途:
- 初始化静态变量。
- 加载静态资源(如配置文件)。
示例:
public class DatabaseConfig {static String url;static String username;static { // 静态代码块url = "jdbc:mysql://localhost:3306/mydb";username = "root";System.out.println("数据库配置已加载");} }
静态内部类
定义:用
static
修饰的内部类,不依赖外部类实例。特点:
- 可直接创建实例:
new Outer.Inner()
。- 不能访问外部类的非静态成员。
- 常用于工具类或单例模式。
示例:
public class Outer {static class Inner { // 静态内部类void print() {System.out.println("静态内部类");}}public static void main(String[] args) {Outer.Inner inner = new Outer.Inner(); // 直接创建inner.print();} }
底层原理:
- 内存分配
- 静态变量存储在方法区(Method Area)(Java 8 后为元空间 MetaSpace)。
- 类加载时初始化,生命周期与类相同。
- 类加载机制
- JVM 首次使用类时加载类信息,静态代码块和静态变量在此阶段初始化。
- 类卸载时静态资源才会释放(通常由 JVM 管理)。
注意事项:
场景 规则 访问权限 静态方法只能访问静态成员,非静态方法可访问静态和非静态成员。 多线程安全 静态变量是共享资源,需通过同步机制(如 synchronized
)保证线程安全。继承与重写 静态方法不能被子类重写(但可以隐藏),且不支持 @Override
。设计模式 过度使用 static
会导致代码耦合度高,违反面向对象设计原则。为什么静态方法不能访问非静态成员?
非静态成员依赖对象实例存在,而静态方法在类加载时即可调用,此时对象可能尚未创建。
静态变量与实例变量的区别?
维度 静态变量 实例变量 归属 类 对象实例 内存分配 类加载时分配(方法区) 对象创建时分配(堆内存) 生命周期 与类共存亡 与对象共存亡
13.继承
定义:
继承 是面向对象编程(OOP)的三大特性之一(封装、继承、多态),允许一个类(子类/派生类)基于另一个类(父类/基类)构建,复用父类的属性和方法,并可以扩展或修改其功能。
核心作用:
- 代码复用:避免重复编写公共代码。
- 层次化设计:建立类之间的层次关系(如动物 → 猫 → 布偶猫)。
- 多态支持:通过父类引用操作子类对象。
语法:使用
extends
关键字实现继承class 父类 {// 父类属性和方法 }class 子类 extends 父类 {// 子类特有的属性和方法 }
继承的成员范围:
- 子类可继承的成员
public
和protected
修饰的属性和方法。- 默认访问权限(无修饰符)的成员(若子类与父类在同一包中)。
- 不可继承
private
成员。- 父类的构造方法(但可通过
super()
调用)。子类可重写父类的方法,以提供特定实现。
class Animal {public void makeSound() {System.out.println("动物发出声音");} }class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("喵喵");} }
构造方法与继承
创建子类对象时,父类构造方法优先执行。
class Parent {Parent() {System.out.println("父类构造方法");} }class Child extends Parent {Child() {super(); // 默认隐含调用父类无参构造System.out.println("子类构造方法");} }// 输出: // 父类构造方法 // 子类构造方法
若父类只有带参构造方法,子类必须显式调用
super(参数)
。class Parent {Parent(int value) { ... } }class Child extends Parent {Child() {super(10); // 必须显式调用} }
单继承与多继承
Java只支持单继承(一个子类只能有一个直接父类),但可以通过接口(
implements
)实现多继承的效果
14.this和super关键字
this
关键字
作用:
- 指向当前对象的引用,用于在类的内部访问当前对象的成员(属性、方法、构造方法)。
- 主要解决变量名冲突(如局部变量与成员变量同名)。
使用场景:
区分成员变量和局部变量
public class Person {private String name; // 成员变量public void setName(String name) { // 参数(局部变量)this.name = name; // 用 this 区分同名变量} }
调用当前对象的其他构造方法(必须在构造方法的第一行使用)
public class Person {private String name;private int age;// 无参构造方法调用有参构造方法public Person() {this("Unknown", 0); // 调用下面的构造方法}public Person(String name, int age) {this.name = name;this.age = age;} }
返回当前对象本身
public class Counter {private int count;public Counter increment() {count++;return this; // 返回当前对象,支持链式调用} }// 使用示例 Counter counter = new Counter().increment().increment();
注意事项:
- 不能用于静态方法(
static
方法属于类,不依赖对象)。- 不能单独使用(必须指向具体的成员)。
super
关键字
作用:
- 指向父类对象的引用,用于在子类中访问父类的成员(属性、方法、构造方法)。
- 主要解决继承中的成员覆盖问题。
使用场景:
调用父类的构造方法
必须在子类构造方法的第一行使用。
如果父类没有无参构造方法,必须显式调用
super(...)
。class Animal {private String type;public Animal(String type) {this.type = type;} }class Dog extends Animal {public Dog() {super("犬科"); // 显式调用父类有参构造方法} }
访问父类的成员变量或方法
当子类覆盖父类方法时,用
super
调用父类原始方法。class Animal {public void eat() {System.out.println("动物在吃东西");} }class Dog extends Animal {@Overridepublic void eat() {super.eat(); // 先调用父类的 eat()System.out.println("狗在啃骨头");} }
访问父类被隐藏的成员变量
class Parent {String name = "Parent"; }class Child extends Parent {String name = "Child";public void printNames() {System.out.println(super.name); // 输出 ParentSystem.out.println(this.name); // 输出 Child} }
注意事项:
- 不能用于静态上下文(静态方法或静态块)。
- 不能单独使用(必须指向具体的父类成员)。
注意:
- 在构造方法中,
this()
和super()
不能共存,必须放在第一行且只能调用一次。super
只能直接访问直接父类,无法跨级访问祖父类。
示例:
class Vehicle {String type;public Vehicle(String type) {this.type = type;}public void start() {System.out.println(type + "启动");} }class Car extends Vehicle {String brand;public Car(String brand) {super("汽车"); // 调用父类构造方法this.brand = brand;}@Overridepublic void start() {super.start(); // 调用父类的 start()System.out.println(brand + "汽车正在行驶");} }public class Main {public static void main(String[] args) {Car car = new Car("丰田");car.start();} }// 输出: // 汽车启动 // 丰田汽车正在行驶
15.抽象类 VS 接口
什么是抽象?
抽象(Abstraction)是面向对象编程的核心思想之一,指提取对象的本质特征,忽略具体实现细节。通过抽象,可以定义统一的规范或模板,让具体实现由子类或实现类完成。
抽象类(Abstract Class)
定义:用
abstract
修饰的类,称为抽象类。它可以包含抽象方法(无具体实现)和具体方法(有实现),用于定义部分实现的模板。核心特性:
- 不能被实例化:只能通过子类继承后使用。
- 可以包含抽象方法:用
abstract
修饰的方法,无方法体。- 可以包含具体方法:普通方法的实现。
- 可以定义成员变量:与普通类相同。
- 可以有构造方法:用于子类初始化。
示例:
public abstract class Animal {// 抽象方法(无实现)public abstract void makeSound();// 具体方法(有实现)public void eat() {System.out.println("动物进食");} }
使用场景:
- 定义模板方法模式:父类定义算法骨架,子类实现具体步骤。
- 部分方法需复用:抽象类中既有通用实现,又预留扩展点。
- 需要状态管理:抽象类可定义成员变量保存状态。
接口(Interface)
定义:用
interface
定义的类型,用于描述对象的行为规范。接口中的方法默认是抽象的(Java 8 前),支持多继承。核心特性:
- 默认方法(Default Method):用
default
修饰,提供默认实现。- 静态方法(Static Method):用
static
修饰,直接通过接口调用。- 私有方法(Java 9+):用
private
修饰,辅助默认方法。- 成员变量默认是
public static final
:即常量。- 不能定义构造方法:无法实例化。
示例:
public interface Flyable {// 抽象方法(默认 public abstract)void fly();// 默认方法(Java 8+)default void glide() {System.out.println("滑翔中");}// 静态方法(Java 8+)static int getMaxSpeed() {return 1000;} }
使用场景:
- 定义行为规范:如
Runnable
接口定义线程任务。- 实现多继承:一个类可实现多个接口。
- 解耦组件:通过接口隔离实现与调用方。
对比
维度 抽象类(Abstract Class) 接口(Interface) 关键字 abstract class
interface
实例化 不能直接实例化 不能直接实例化 成员变量 普通变量(可非 final) 默认 public static final
(常量)构造方法 可以有 不能有 继承关系 单继承(一个子类只能继承一个抽象类) 多继承(一个类可实现多个接口) 设计目的 代码复用,定义部分实现 定义行为规范,解耦设计 如何选择:
- 优先使用接口:避免继承带来的强耦合。
- 抽象类用于代码复用:当多个类有共同逻辑时。
16.多态
定义:多态(Polymorphism) 是面向对象编程(OOP)的核心特性之一,指同一操作作用于不同对象时,可以有不同的行为。它允许使用统一的接口处理不同类型的对象,从而提高代码的灵活性和可扩展性。
Java 中的多态分为两类:
类型 实现方式 特点 编译时多态 方法重载(Overloading) 根据参数列表在编译时确定调用的方法。 运行时多态 方法重写(Overriding) + 继承 根据对象实际类型在运行时确定调用的方法。 运行时多态(动态绑定)
核心机制:JVM 在运行时根据对象的实际类型(而非引用类型)动态绑定要执行的方法。
条件:
- 继承关系:存在父类与子类。
- 方法重写:子类重写父类的方法。
- 向上转型:父类引用指向子类对象。
示例:
class Animal {public void sound() {System.out.println("动物发出声音");} }class Dog extends Animal {@Overridepublic void sound() {System.out.println("汪汪");} }class Cat extends Animal {@Overridepublic void sound() {System.out.println("喵喵");} }public class Main {public static void main(String[] args) {Animal a1 = new Dog(); // 向上转型Animal a2 = new Cat();a1.sound(); // 输出 "汪汪"(动态绑定)a2.sound(); // 输出 "喵喵"} }
应用场景:
- 统一接口处理不同对象。
- 结合工厂模式,通过多态创建不同子类对象。
多态与类型转换
向上转型
子类对象赋值给父类引用(自动完成)。
特点:安全,但只能访问父类声明的方法。
Animal animal = new Dog(); // 向上转型
向下转型
父类引用强制转换为子类类型(需显式转换)。
风险:可能抛出
ClassCastException
。安全做法:使用
instanceof
检查。if (animal instanceof Dog) {Dog dog = (Dog) animal; // 安全向下转型dog.bark(); }
注意事项:
- 静态方法不支持重写,无多态性(通过类名调用)。
- 私有方法不可被重写,无多态性。
- final 方法禁止重写,无多态性。
- 成员变量无多态性,访问时取决于引用类型。
- 构造方法不可被重写,无多态性。
17.权限修饰符
权限修饰符总览
修饰符 类内部 同包内 子类(不同包) 其他包 public
✅ ✅ ✅ ✅ protected
✅ ✅ ✅ ❌ 默认(不写) ✅ ✅ ❌ ❌ private
✅ ❌ ❌ ❌ 注:
- 默认权限:不使用任何修饰符,称为包级私有(package-private)。
- 子类权限:
protected
允许不同包的子类访问父类成员。- 类本身的修饰符:外部类只能使用
public
或默认权限(不能是protected
或private
)。
public
(公开)
作用范围:任何地方均可访问。
典型场景:
- 开放给外部调用的方法(如工具类方法)。
- 常量(
public static final
)。- 主类(包含
main
方法的类必须用public
)。示例:
public class Calculator {public static final double PI = 3.14159; // 公开常量public int add(int a, int b) { // 公开方法return a + b;} }
protected
(受保护)
作用范围:本类、同包类、不同包的子类。
典型场景:
- 父类中希望被子类继承或重写的方法或属性。
- 框架设计中需要被子类扩展的成员。
示例:
public class Animal {protected void breathe() { // 子类可继承并调用System.out.println("呼吸");} }class Dog extends Animal {public void showBreathe() {breathe(); // 子类可直接调用父类的 protected 方法} }
默认权限(包级私有)
作用范围:本类、同包类。
典型场景:
- 内部工具方法或属性,不希望被其他包访问。
- 模块化设计中,包内协作的类。
示例:
class Logger { // 默认权限,只能在同包内使用void log(String message) { // 默认权限方法System.out.println("[LOG] " + message);} }
private
(私有)
作用范围:仅本类内部。
典型场景:
- 隐藏类的内部实现细节(如成员变量)。
- 防止外部直接修改数据,通过公共方法(getter/setter)控制访问。
示例:
public class BankAccount {private double balance; // 私有属性,外部无法直接访问public void deposit(double amount) { // 公开方法控制存取if (amount > 0) {balance += amount;}}public double getBalance() { // 提供公共读取接口return balance;} }
注意事项:
- 类的修饰符
- 外部类只能使用
public
或默认权限。- 内部类可以是
private
或protected
。- 方法重写时的权限
- 子类重写父类方法时,权限不能缩小(如父类方法是
public
,子类不能改为protected
)。- 构造方法的权限
- 构造方法可以是任意权限(如
private
用于单例模式)。建议:
- 最小化访问原则:
- 优先使用最严格的权限(如
private
),仅在必要时放宽。- 减少代码耦合,提高安全性。
- 封装数据:
- 成员变量尽量设为
private
,通过公共方法(getter/setter)控制访问。- 避免直接暴露内部状态。
- 模块化设计:
- 使用默认权限隐藏包内实现细节。
- 通过
public
类或方法对外提供接口。
18.final关键字
定义:
final
是 Java 中用于限制类、方法或变量的修改或继承的关键字,其核心目标是增强代码的安全性、不可变性和设计约束。作用:
修饰对象 作用 变量 变量值(或引用)不可变(常量)。 方法 方法不能被子类重写。 类 类不能被继承。
修饰变量
基本数据类型变量
变量值一旦初始化,不可修改。
final int MAX_VALUE = 100; // MAX_VALUE = 200; // 编译错误:无法为final变量赋值
引用类型变量
引用不可变(即不能指向其他对象),但对象内部状态可修改。
final List<String> list = new ArrayList<>(); list.add("Java"); // 允许:修改对象内容 // list = new LinkedList<>(); // 编译错误:不能改变引用
成员变量与局部变量
成员变量:必须显式初始化(可在声明时、构造方法或初始化块中赋值)。
局部变量:只需在使用前初始化一次。
class Example {final int a = 10; // 声明时初始化final int b;Example() {b = 20; // 构造方法中初始化} }
修饰方法
禁止子类重写
确保父类方法逻辑不被修改。
class Parent {public final void show() {System.out.println("父类方法");} }class Child extends Parent {// 编译错误:无法重写final方法// public void show() { ... } }
与
private
的隐式final
若方法为
private
,则隐式具有final
效果(子类无法访问,更无法重写)。class Parent {private void method() {} // 隐式final }class Child extends Parent {// 合法:实际是子类的新方法,非重写private void method() {} }
修饰类
禁止继承
保证类不可被扩展(如
String
、Integer
等核心类均为final
)。final class ImmutableClass { ... }// 编译错误:无法继承final类 // class SubClass extends ImmutableClass { ... }
设计不可变类
若类为
final
,且所有字段为final
,则对象创建后状态不可变。public final class ImmutablePoint {private final int x;private final int y;public ImmutablePoint(int x, int y) {this.x = x;this.y = y;}// 仅提供getter,无setter }
19.构造代码块 VS 静态代码块
在 Java 中,代码块(Code Block)是一段被大括号
{}
包围的代码,用于控制变量的作用域或定义代码的执行逻辑。实例代码块(构造代码块)
定义:直接写在类中,无修饰符,每次创建对象时执行(在构造方法之前)。
作用:初始化实例变量或执行对象共有的初始化逻辑。
语法:
{// 初始化实例变量或通用逻辑 }
示例:
public class Car {String brand;int speed;// 实例代码块:每次 new 对象时执行{speed = 0; // 所有 Car 对象初始速度为 0System.out.println("实例代码块执行:车辆已启动");}public Car(String brand) {this.brand = brand;} }
静态代码块
定义:用
static
修饰,属于类级别,在类加载时执行一次。作用:初始化静态变量或加载静态资源(如配置文件)。
语法:
static {// 初始化静态资源 }
示例:
public class DatabaseConfig {static String url;static String username;// 静态代码块:类加载时读取配置static {url = "jdbc:mysql://localhost:3306/mydb";username = "admin";System.out.println("静态代码块执行:数据库配置已加载");} }
实例代码块 vs 静态代码块
- 实例代码块:每次
new
对象时执行(在构造方法之前)。- 静态代码块:类加载时执行一次(仅一次)。
示例:
public class ExecutionOrder {static {System.out.println("静态代码块执行");}{System.out.println("实例代码块执行");}public ExecutionOrder() {System.out.println("构造方法执行");}public static void main(String[] args) {new ExecutionOrder();new ExecutionOrder();} }// 输出: // 静态代码块执行 // 实例代码块执行 // 构造方法执行 // 实例代码块执行 // 构造方法执行
使用场景与建议
- 实例代码块
- 场景:多个构造方法共有的初始化逻辑(如设置默认值)。
- 建议:可将通用逻辑提取到私有方法中,由构造方法调用。
- 静态代码块
- 场景:初始化全局配置(如数据库连接)、加载静态资源(如图片、文件)。
- 建议:避免在静态代码块中执行耗时操作(影响类加载速度)。
总结
- 静态代码块处理类级初始化,实例代码块处理对象级初始化。
- 优先选择构造方法或方法封装逻辑,避免滥用代码块!
20.内部类
在 Java 中,内部类(Inner Class) 是定义在另一个类内部的类,它可以访问外部类的成员,并实现更灵活的代码封装。
成员内部类
定义:直接定义在外部类的成员位置(与属性、方法同级)。
特点:
- 可以访问外部类的所有成员(包括
private
)。- 依赖外部类实例存在(不能有静态成员,除非用
static final
常量)。示例:
public class Outer {private int outerField = 10;// 成员内部类class Inner {void print() {System.out.println("访问外部类字段:" + outerField); // 直接访问外部类成员}} }
Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); // 必须通过外部类实例创建
静态内部类
定义:用
static
修饰的内部类。特点:
- 不依赖外部类实例(可直接创建)。
- 不能直接访问外部类的非静态成员(只能访问静态成员)。
示例:
public class Outer {private static int staticField = 20;private int instanceField = 30;static class StaticInner {void print() {System.out.println(staticField); // 合法// System.out.println(instanceField); // 错误!无法访问非静态成员}} }
Outer.StaticInner inner = new Outer.StaticInner(); // 直接创建
局部内部类
定义:定义在方法或代码块内部的类。
特点:
- 作用域仅限于所在方法或代码块。
- 可以访问外部类的成员,但只能访问所在方法的
final
或 effectively final 局部变量。示例:
public class Outer {private int outerField = 40;public void method() {int localVar = 50; // 必须为 final 或 effectively finalclass LocalInner {void print() {System.out.println(outerField); // 合法System.out.println(localVar); // 合法(localVar 不可修改)}}LocalInner inner = new LocalInner();inner.print();} }
匿名内部类
定义:没有名字的局部内部类,通常用于简化代码(如事件监听、线程实现)。
特点:
- 直接继承父类或实现接口。
- 只能使用一次(无法复用)。
示例:
public interface ClickListener {void onClick(); }public class Button {public void setOnClickListener(ClickListener listener) {listener.onClick();} }// 使用匿名内部类 Button button = new Button(); button.setOnClickListener(new ClickListener() {@Overridepublic void onClick() {System.out.println("按钮被点击!");} });
应用场景:
封装性增强
场景:将仅用于某个外部类的辅助逻辑封装在内部(如链表节点
Node
)。public class LinkedList {private Node head;// 成员内部类:外部无需关心 Node 的实现private class Node {int data;Node next;} }
回调与事件处理
场景:匿名内部类简化事件监听(如 Android 点击事件)。
// Java Swing 示例 JButton button = new JButton("提交"); button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("提交表单");} });
访问外部类私有成员
场景:内部类直接操作外部类私有属性。
public class Outer {private int secret = 100;class Inner {void revealSecret() {System.out.println("秘密是:" + secret); // 直接访问 private 成员}} }
静态工具类
场景:静态内部类实现与外部类相关的工具逻辑。
public class MathUtils {// 静态内部类:提供特定算法public static class Calculator {public static int add(int a, int b) {return a + b;}} }// 使用 int sum = MathUtils.Calculator.add(2, 3);
内部类是实现高内聚、低耦合的重要手段,但需根据场景选择合适类型,避免滥用!
21.异常
定义:异常(Exception) 是程序执行过程中发生的非正常事件,它会中断程序的正常流程。Java 通过异常机制提供了一种结构化的错误处理方式。
分类:
Java 异常类均继承自
Throwable
,分为三大类:
类型 特点 示例 Error JVM 严重错误,程序无法恢复(通常不处理) OutOfMemoryError
检查型异常(Checked Exception) 编译时强制要求处理(继承自 Exception
但非RuntimeException
的子类)IOException
,SQLException
非检查型异常(Unchecked Exception) 运行时异常,通常由程序逻辑错误引起( RuntimeException
及其子类)NullPointerException
,ArrayIndexOutOfBoundsException
异常处理:
使用
try-catch-finally
块捕获并处理异常
核心思想:在代码中直接捕获异常并处理,避免程序终止。
适用场景:当前方法明确知道如何处理异常时(如重试、回滚、日志记录等)。
语法:
try {// 可能抛出异常的代码 } catch (ExceptionType1 e1) {// 处理特定异常 } catch (ExceptionType2 e2) {// 处理其他异常 } finally {// 无论是否异常,最终执行的代码(如释放资源) }
示例:
try {FileInputStream fis = new FileInputStream("file.txt"); } catch (FileNotFoundException e) {System.out.println("文件未找到"); } finally {if (fis != null) fis.close(); // 需处理IOException }
使用
throws
声明抛出异常
核心思想:将异常抛给调用者处理,当前方法不直接处理。
适用场景:当前方法无法处理异常(如工具类方法、底层逻辑),需由上层调用者决定如何应对。
示例
public void readFile() throws FileNotFoundException, IOException {FileReader file = new FileReader("test.txt");// 其他可能抛出 IOException 的操作 }
throw
抛出异常
手动抛出异常对象,可以是自定义异常。
示例:
if (age < 0) {throw new IllegalArgumentException("年龄不能为负数"); }
自定义异常
步骤:
- 继承
Exception
(检查型异常)或RuntimeException
(非检查型异常)。- 提供构造方法(通常调用父类构造)。
示例:
public class InsufficientFundsException extends RuntimeException {public InsufficientFundsException(String message) {super(message);} }// 使用 if (balance < amount) {throw new InsufficientFundsException("余额不足"); }
Error 和 Exception 的区别?
- Error:JVM 严重问题(如内存溢出),程序无法恢复。
- Exception:可捕获处理的异常(检查型需处理,非检查型通常不强制)。
22.为什么String类可以不用new创建对象?
在Java中,
String
类可以不用new
关键字创建对象,这是由**字符串常量池(String Pool)**机制和Java对字符串字面量的特殊处理共同实现的。字符串常量池(String Pool)
什么是字符串常量池?
字符串常量池是Java堆内存中的一块特殊存储区域,用于缓存字符串字面量。当通过字面量(如
"abc"
)创建字符串时,JVM会先在字符串常量池中检查是否存在相同内容的字符串:
- 如果存在:直接返回池中已有字符串的引用,不创建新对象。
- 如果不存在:在池中创建该字符串对象,并返回引用。
目的:减少重复字符串的内存占用,提升性能。
示例:
String s1 = "abc"; // 第一次创建,池中没有,故在池中新建对象 String s2 = "abc"; // 直接复用池中的"abc",s1和s2指向同一对象 System.out.println(s1 == s2); // 输出 true(引用相同)
new String()
与字面量的区别
使用
new
关键字:每次都会在堆中强制创建新对象,即使内容相同。
String s3 = new String("abc"); // 在堆中新建对象,不检查常量池 String s4 = new String("abc"); // 再新建一个对象 System.out.println(s3 == s4); // 输出 false(引用不同)
使用字面量:
直接利用常量池,避免重复构建。
String s5 = "abc"; // 从常量池获取 String s6 = "abc"; // 同上 System.out.println(s5 == s6); // 输出 true(引用相同)
字符串的不可变性
String
类被设计为不可变(所有修改操作都返回新对象),这使得常量池可以安全地缓存字符串:
- 多个引用共享同一字符串时,无需担心内容被意外修改。
- 缓存字符串的哈希值,提升性能(如
HashMap
的键)。编译时优化
字面量的处理:
在编译阶段,字符串字面量会被直接写入类的常量池。当类加载时,JVM会将这些字面量预先加载到字符串常量池中。
String s7 = "hello" + " world"; // 编译期优化为"hello world" // 等价于 String s7 = "hello world";
intern
方法手动将字符串添加到常量池:调用
intern()
方法时,如果池中已有相同内容的字符串,返回其引用;否则将当前字符串添加到池中。String s8 = new String("xyz").intern(); String s9 = "xyz"; System.out.println(s8 == s9); // 输出 true
总结
Java通过字符串常量池和字面量处理机制,使得直接赋值(如
"abc"
)能够复用已有对象,无需显式使用new
。这种处理能够节省内存、提升性能,同时依赖字符串的不可变性保证安全性。
23.增强for
增强 for 循环(也称为 for-each 循环)是 Java 5 引入的语法糖,旨在简化集合和数组的遍历操作。它隐藏了迭代器或索引的细节,使代码更简洁易读。
基本语法:
for (元素类型 变量名 : 集合或数组) {// 操作变量 }
示例:
List<String> list = Arrays.asList("A", "B", "C"); for (String s : list) {System.out.println(s); // 输出 A, B, C }int[] array = {1, 2, 3}; for (int num : array) {System.out.println(num); // 输出 1, 2, 3 }
原理:
遍历数组:编译器会将其转换为传统索引循环
// 源码:for (int num : array) { ... } for (int i = 0; i < array.length; i++) {int num = array[i];// 操作 num }
遍历集合:编译器会调用集合的
iterator()
方法,使用迭代器遍历// 源码:for (String s : list) { ... } Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) {String s = iterator.next();// 操作 s }
注意事项:
无法直接访问索引
若需索引,需改用传统 for 循环或额外计数变量。
int index = 0; for (String s : list) {System.out.println(index + ": " + s);index++; }
不能修改集合结构
遍历时直接调用集合的
add()
或remove()
会抛出ConcurrentModificationException
。
相关文章:
Java入门首周精要:从基础语法到面向对象核心解析
文章目录 Java入门首周精要:从基础语法到面向对象核心解析1.Java类名与文件名的一致性规则2.Java和C语言中char类型的区别3.Java中的注释4.Java中的‘’‘’运算符5.Java的输入输出6.方法(重载&重写)方法的重载方法的重写 7.面向对象&…...
嵌入式AI开源生态指南:从框架到应用的全面解析
嵌入式AI开源生态指南:从框架到应用的全面解析 引言 随着人工智能技术的迅速发展,将AI能力部署到边缘设备上的需求日益增长。嵌入式AI通过在资源受限的微控制器上运行机器学习模型,实现了无需云连接的本地智能处理,大幅降低了延…...
MCP server的stdio和SSE分别是什么?
文章目录 一、Stdio:本地进程间通信的核心二、SSE:远程通信与实时推送的利器三、Stdio vs SSE:关键差异对比四、如何选择?场景驱动的决策指南五、实战建议与避坑指南实际操作结语在AI应用开发中,MCP(Model Context Protocol)协议正成为连接大模型与外部资源的核心桥梁。…...
哈希表(闭散列)的实现
目录 概念及定义 闭散列的介绍 闭散列底层实现 哈希表的定义 哈希表的构造 哈希表扩容 哈希表插入 哈希表删除 哈希表查找 概念及定义 哈希表,也成为散列表,在C中unordered_set和unordered_map的底层实现依靠的都是哈希表。 map和set的底层是红…...
Shiro学习(六):Shiro整合CAS实现单点登录
一、单点登录介绍 单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。 SSO的定义是在多个[应用],用户只需要登录一次就可以访问所有相互信任的应用系统。 一般这种单点登录的实现方案&…...
HAProxy-ACL实战篇
HAProxy-ACL实战篇 IP说明172.25.254.101客户端172.25.254.102haproxy服务器172.25.254.103web1172.25.254.104web2 ACL示例-域名匹配 # 172.25.254.102 [rootRocky ~]# cat /etc/haproxy/conf.d/test.cfg frontend magedu_http_portbind 172.25.254.102:80mode httpbalanc…...
以下是针对该 Ansible 任务的格式检查和优化建议
以下是针对该 Ansible 任务的格式检查和优化建议: 目录 一、格式检查原始代码问题分析修正后的标准格式 二、推荐增强功能1. 添加可执行权限2. 显式指定 Shell 解释器3. 添加错误处理 三、完整 Playbook 示例四、验证脚本兼容性五、常见错误总结 一、格式检查 原始…...
C++语言的测试覆盖率
C语言的测试覆盖率分析与实践 引言 在软件开发过程中,测试覆盖率是一项重要的质量指标,它帮助开发者评估代码的测试效果,确保软件的可靠性与稳定性。尤其在C语言的开发中,由于其复杂的特性和丰富的功能,测试覆盖率的…...
如何使用 DrissionPage 进行网页自动化和爬取
在这个技术博客中,我们将向大家展示如何使用 DrissionPage 进行网页自动化操作与数据爬取。DrissionPage 是一个基于 Playwright 的 Python 自动化工具,它允许我们轻松地控制浏览器进行网页爬取、测试以及自动化操作。与其他工具(如 Selenium…...
设计模式 Day 3:抽象工厂模式(Abstract Factory Pattern)详解
经过前两天的学习,我们已经掌握了单例模式与工厂方法模式,理解了如何控制实例个数与如何通过子类封装对象的创建逻辑。 今天,我们将进一步深入“工厂”体系,学习抽象工厂模式(Abstract Factory Pattern)&a…...
TensorRT 有什么特殊之处
一、TensorRT的定义与核心功能 TensorRT是NVIDIA推出的高性能深度学习推理优化器和运行时库,专注于将训练好的模型在GPU上实现低延迟、高吞吐量的部署。其主要功能包括: 模型优化:通过算子融合(合并网络层)、消除冗余…...
SQL注入-盲注靶场实战(手写盲注payload)--SRC获得库名即可
布尔盲注 进入页面 注入点 ’ and 11 and 12 得知为布尔盲注 库名长度 and length(database()) 8 抓包(浏览器自动进行了url编码)爆破 得知为 12 库名字符 1 and ascii(substr(database(),1,1))112 – q (这里如果不再次抓包…...
http://noi.openjudge.cn/_2.5基本算法之搜索_1804:小游戏
文章目录 题目深搜代码宽搜代码深搜数据演示图总结 题目 1804:小游戏 总时间限制: 1000ms 内存限制: 65536kB 描述 一天早上,你起床的时候想:“我编程序这么牛,为什么不能靠这个赚点小钱呢?”因此你决定编写一个小游戏。 游戏在一…...
Windows Flip PDF Plus Corporate PDF翻页工具
软件介绍 Flip PDF Plus Corporate是一款功能强大的PDF翻页工具,也被称为名编辑电子杂志大师。这款软件能够迅速将PDF文件转换为具有翻页动画效果的电子书,同时保留原始的超链接和书签。无论是相册、视频、音频,还是Flash、视频和链接&#…...
Java八股文-List
集合的底层是否加锁也就代表是否线程安全 (一)List集合 一、数组 array[1]是如何通过索引找到堆内存中对应的这块数据的呢? (1)数组如何获取其他元素的地址值 (2)为什么数组的索引是从0开始的,不可以从1开始吗 (3)操作数组的时间复杂度 ①查找 根据索引查询 未…...
btrfs , ext4 , jfs , xfs , zfs 对比 笔记250406
btrfs , ext4 , jfs , xfs , zfs 对比 笔记250406 特性Btrfsext4JFSXFSZFS定位现代多功能传统稳定轻量级高性能大文件企业级存储最大文件/分区16EB / 16EB16TB / 1EB4PB / 32PB8EB / 8EB16EB / 25610⁵ ZB快照✅ 支持❌ 不支持❌ 不支持❌ 不支持✅ 支持透明压缩✅ (Zstd/LZO)❌…...
Meta上新Llama 4,到底行不行?
这周AI圈被Meta的“深夜突袭”炸开了锅。 Llama 4家族带着三个新成员,直接杀回开源模型战场,连扎克伯格都亲自站台喊话:“我们要让全世界用上最好的AI!” 但别急着喊“王炸”,先看看它到底强在哪。 这次Meta玩了个狠招…...
显示器工艺简介
华星光电显示器的生产工艺流程介绍,从入厂原料到生产出显示器的整体工艺介绍 华星光电显示器的生产工艺流程主要包括以下几个阶段,从原材料入厂到最终显示器的生产: 原材料准备 玻璃基板:显示器的核心材料,通常采用超…...
音乐软件Pro版!内置音源,听歌自由,一键畅享!
今天给大家介绍一款超实用的音乐软件——LX音乐Pro版。原版LX音乐需要用户自行导入音源才能正常使用,但此次推出的Pro版已经内置了音源,省去了繁琐的操作步骤,使用起来更加便捷 这款软件不仅支持歌曲搜索,还能搜索歌单,…...
Spring 中有哪些设计模式?
🧠 一、Spring 中常见的设计模式 设计模式类型Spring 中的应用场景单例模式创建型默认 Bean 是单例的工厂模式创建型BeanFactory、FactoryBean抽象工厂模式创建型ApplicationContext 提供多个工厂接口代理模式结构型AOP 动态代理(JDK/CGLIB)…...
R语言使用ggplot2作图
在ggplot2中,图是采用串联起来()号函数创建的。每个函数修改属于自己的部分。比如,ggplot()geom()...... aes(x, y, colour a,shape a,size a.......) ggplot2中画图常用的五大块内容 数据(data)及一系列将数据中的变量对应到图…...
GenerationMixin概述
类 类名简单说明GenerateDecoderOnlyOutput继承自 ModelOutput,适用于非束搜索方法的解码器-only模型输出类。GenerateEncoderDecoderOutput继承自 ModelOutput,适用于非束搜索方法的编码器-解码器模型输出类。GenerateBeamDecoderOnlyOutput继承自 Mod…...
文心快码制作微信小程序
AI时代来临,听说Baidu Comate也推出了自家的编程工具Zulu,可以从零到一帮你生成代码,趁着现在还免费,试试效果如何。这里以开发一个敲木鱼的微信小程序为例 一、需求分析 写小程序需求文档 首先,第一步我要准确描述…...
flutter provider状态管理使用
在 Flutter 中,Provider 是一个轻量级且易于使用的状态管理工具,它基于 InheritedWidget,并提供了一种高效的方式来管理和共享应用中的状态。相比其他复杂的状态管理方案(如 Bloc 或 Riverpod),Provider 更…...
C++——静态成员
目录 静态成员的定义 静态成员变量 编程示例 存在的意义 静态成员函数 类内声明 类外定义 编程示例 静态成员的定义 静态成员在C类中是一个重要的概念,它包括静态成员变量和静态成员函数。静态成员的特点和存在的意义如下: 静态成员变量 1…...
UDP学习笔记(四)UDP 为什么大小不能超过 64KB?
🌐 UDP 为什么大小不能超过 64KB?TCP 有这个限制吗? 在进行网络编程或者调试网络协议时,我们常常会看到一个说法: “UDP 最大只能发送 64KB 数据。” 这到底是怎么回事?这 64KB 是怎么来的?TCP…...
Linux中用gdb查看coredump文件
查看dump的命令: gdb 可执行文件 dump文件路径查看函数调用栈 (gdb)bt查看反汇编代码 (gdb)disassemble查看寄存器的值 (gdb)info all-registers如果通过上述简单命令无法排查,还是通过-g参数编译带符号表的可执行文件,再用gdb查看...
PyTorch 深度学习 || 7. Unet | Ch7.1 Unet 框架
1. Unet 框架...
LeetCode 热题 100 堆
215. 数组中的第K个最大元素 给定整数数组 nums 和整数 k,请返回数组中第 **k** 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 …...
LeetCode栈 155. 最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int get…...
Linux系统03---文件操作时间编程
目录 文件操作 1.1 缓冲区 1.2 基于缓冲区的文件操作---高级 IO 1.3 基于非缓冲区的文件操作—低级 IO 1.3.1 文件描述符 int fd; 1.3.2 函数名:open() 1.3.3 函数名:close() 1.3.4 函数名:write() 1.3.5 函数名:read(…...
4月5日作业
需求: 1.按照图示的VLAN及IP地址需求,完成相关配置 2.要求SW 1为VLAN 2/3的主根及主网关 SW2为VLAN 20/30的主根及主网关,SW1和 SW2互为备份 3.可以使用super vlan 4.上层通过静态路由协议完成数据通信过程 5.AR1为企业出口路由器…...
新一代AI架构实践:数字大脑AI+智能调度MCP+领域执行APP的黄金金字塔体系
新一代AI架构实践:数字大脑智能调度领域执行的黄金金字塔体系 一、架构本质的三层穿透性认知 1.1 核心范式转变(CPS理论升级) 传统算法架构:数据驱动 → 特征工程 → 模型训练 → 业务应用 新一代AI架构:物理规律建…...
低代码开发:重塑软件开发的未来
在数字化转型的浪潮中,企业对软件开发的需求呈爆炸式增长。然而,传统软件开发模式面临着开发周期长、成本高、技术门槛高等诸多挑战。低代码开发平台(Low-Code Development Platform)应运而生,它通过可视化编程和拖拽式…...
小型园区网实验作业
拓扑搭建: 实验需求: 1、按照图示的VLAN及IP地址需求,完成相关配置 2、要求SW1为VLAN 2/3的主根及网关 SW2 为VLAN 20/30 的主根及主网关 SW1和SW2互为备份 3、可以使用super vlan 4、上层通过静态路由协议完成数据通信过程 5、A…...
Gateway 网关 快速开始
一、核心概念 路由(route) 路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的 URL 和配置的路由匹配。 断言(predicates) 断言函数允许开发者去定义匹配 Http Request 中…...
C++中如何使用STL中的list定义一个双向链表,并且实现增、删、改、查操作
一、STL中的 list 是双向链表,但不是循环链表,通过指针访问结点数据,它的内存空间可以是不连续的,使用它能高效地进行各种操作。 二、代码 #include <bits/stdc.h> using namespace std;// 打印链表元素的函数 void print…...
shell脚本中捕获键盘中断信号trap
在 Shell 脚本中,可以通过 trap 命令捕获键盘中断信号(通常是 SIGINT,即 CtrlC)。以下是具体的实现方法: 1.使用 trap 捕获键盘中断信号 trap 命令用于捕获信号并执行相应的命令或函数。SIGINT(信号编号为 …...
让ChatGPT用DeepReaserch指导进行学术写作
目录 ChatGPT在学术论文写作中的作用与分阶段提示词指南 1.选题阶段(确定研究课题方向) 2.文献综述阶段(调研与综述已有研究) 3.研究设计阶段(设计研究方法与框架) 4.撰写正文阶段(撰写各部…...
Compose笔记(十四)--LazyColumn
这一节了解一下Compose中的LazyColumn,在Jetpack Compose 中,LazyColumn 是一个用于高效显示长列表或可滚动垂直布局的组件。它类似于传统 Android 开发中的 RecyclerView,但专为 Compose 的声明式 UI 框架设计,能够显著优化性能&…...
CNN-SE-Attention-ITCN多特征输入回归预测(Matlab完整源码和数据)
CNN-SE-Attention-ITCN多特征输入回归预测(Matlab完整源码和数据) 目录 CNN-SE-Attention-ITCN多特征输入回归预测(Matlab完整源码和数据)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.一种适合光伏功率回归预测的高创…...
Spring Data JPA中的List底层:深入解析ArrayList的奥秘!!!
🌟 Spring Data JPA中的List底层:深入解析ArrayList的奥秘 💡 你是否好奇过,为什么Spring Data JPA的查询方法返回的List<T>总是默认为ArrayList?本文将通过技术原理解析、验证实验和性能优化指南,为…...
redis高并发缓存架构与性能优化
Redlock实现原理 超过半数redis节点加锁成功才算成功加锁。 Redlock存在问题 如果主节点挂掉,还没有同步到从节点,重新选举出主节点,那加锁就没有加到这个新的主节点上。 如果增加redis主节点数,那么加锁的性能更差,要…...
解锁多邻国:全方位语言学习新体验
解锁多邻国:全方位语言学习新体验 在数字化学习浪潮中,多邻国(Duolingo)凭借独特优势,成为全球超 5 亿用户的语言学习首选。这款 2012 年诞生于美国匹兹堡的应用,2019 年进入中国市场后,…...
Docker部署SeraXNG接入dify报错解决
报错: 设置授权 配置凭据后,工作区中的所有成员都可以在编排应用程序时使用此工具。 SearXNG base URL* 如何获取 PluginInvokeError: {"args":{},"error_type":"ToolProviderCredentialValidationError","message&q…...
Zookeeper的作用详解
Zookeeper作为分布式协调服务,在分布式系统中承担核心协调角色,其作用可归纳为以下核心功能模块: 一、分布式协调与同步 分布式锁管理 提供独占锁和共享锁,通过创建临时顺序节点实现锁的公平竞争。例如,客户端在/distr…...
高频面试题(含笔试高频算法整理)基本总结回顾34
干货分享,感谢您的阅读! (暂存篇---后续会删除,完整版和持续更新见高频面试题基本总结回顾(含笔试高频算法整理)) 备注:引用请标注出处,同时存在的问题请在相关博客留言…...
Dify 与 n8n 对比分析:AI 应用开发与自动化工作流工具的深度比较
Dify 与 n8n 对比分析:AI 应用开发与自动化工作流工具的深度比较 摘要 本文对比分析了 Dify 和 n8n 两款工具的核心定位、功能特点、适用场景及技术门槛。Dify 专注于 AI 应用开发,适合快速搭建智能客服、知识库检索等场景;n8n 则定位于通用…...
Systemd构建容器化微服务集群管理系统
实训背景 你是一家云计算公司的 DevOps 工程师,需为某客户设计一套基于 Docker 的微服务集群管理系统,需求如下: 容器自启管理:确保三个服务(webapp、api、redis)在系统启动时自动运行。依赖顺序控制&…...
手搓多模态-04 归一化介绍
在机器学习中,归一化是一个非常重要的工具,它能帮助我们加速训练的速度。在我们前面的SiglipVisionTransformer 中,也有用到归一化层,如下代码所示: class SiglipVisionTransformer(nn.Module): ##视觉模型的第二层&am…...