链式调用底层
实现链式调用的方式就是每个可以链式调用的方法返回了自身的 this 实例,进而可以链式访问方法。
public class Main {
public static void main(String[] args) {
Adder adder = new Adder();
adder.add(3)
.add(5)
.inc()
.add(10);
System.out.println(adder.value());
}
}
class Adder {
private int sum = 0;
public Adder add(int n) {
sum += n;
return this;
}
public Adder inc() {
sum ++;
return this;
}
public int value() {
return sum;
}
}包装
底层是:
public final class Integer {
private final int value;
}因此对象创建后其属性具有不变性。 使用 Integer n = Integer.valueOf(100)(静态工厂方法)来让该类去管理对象的创建,而不是每次手动去 new 对象,得不到 JDK 的优化。 包装类型是引用类型(引用类型可以赋值为 null,基本类型不行) 深入理解为什么"所有的整数和浮点数的包装类型都继承自 Number,因此,可以非常方便地直接通过包装类型获取各种基本类型"Number 类是 Java 平台中所有表示数值的类的抽象基类,它定义了一些通用的方法,并且强制要求子类实现。 因此各子类既然是继承自该类的,自然可以实现相应的转换,调用声明的方法。 在一些地方不用显示转换,编译器会自己进行自动装箱和自动拆箱。
JavaBean
一个类中属性的读取满足:
// 读方法:
public Type getXyz()
// 写方法:
public void setXyz(Type value)符合这种条件的 class 被称为JavaBean
内省器
内省(Introspection)在计算机科学和编程语言中,通常指的是一个程序在运行时获取关于自身的类型信息、属性、方法等结构的能力。这种能力允许程序动态地检查和操作对象的状态和行为,而无需在编译时知道这些信息。 比如枚举一个类下的所有 bean:
import java.beans.*;
public class Main {
public static void main(String[] args) throws Exception {
BeanInfo info = Introspector.getBeanInfo(Person.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
System.out.println(pd.getName());
System.out.println(" " + pd.getReadMethod());
System.out.println(" " + pd.getWriteMethod());
}
}
}枚举类
enum 是引用类型,作为常量,因此拥有唯一实例。 可以通过构造方法为枚举类成员增加属性:
enum Weekday {
MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0);
public final int dayValue; // 常量字段
private Weekday(int dayValue) { // 私有构造
this.dayValue = dayValue;
}
}也可以用在 switch 中。
记录类
不变类
一个不变类具有以下特点:
- 定义class时使用
final,无法派生子类; - 每个字段使用
final,保证创建实例后无法修改任何字段。
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int x() {
return this.x;
}
public int y() {
return this.y;
}
}此外,还需要正确覆写 equals() 和 hashCode()。 为了简化这个过程,可以使用 record 来创建一个记录类:
// Record
public class Main {
public static void main(String[] args) {
Point p = new Point(123, 456);
System.out.println(p.x());
System.out.println(p.y());
System.out.println(p);
}
}
record Point(int x, int y) {}自动为我们创建了构造方法,和字段名同名的方法,以及覆写 toString()、equals() 和 hashCode() 方法。 可以直接在构造函数中添加检查逻辑,但不要写明赋值语句,编译器会加上,称之为Compact Constructor(简约构造器)