This constructor runs when you construct objects of the Employee class—giving the instance fields the initial state you want them to have.

public Employee(String n, double s, int year, int month, int day) {
	name = n;
	salary = s;
	hireDay = LocalDate.of(year, month, day);
}

A constructor can only be called in conjunction with the new operator. (就是注意,C++ 那一套别用进来)

看起来,好像没有 C++ 中那套 list initialize

About null

null 仅代表 obj 的缺席,并不适合作为未知数据的替代,对 null 的 invoke 会导致严重问题,所以我们

The “permissive” approach is to turn a null argument into an appropriate non-null value:

if (n == null) name = "unknown"; else name = n;
name = Objects.requireNonNullElse(n, "unknown");

The “tough love” approach is to reject a null argument:

Objects.requireNonNull(n, "The name cannot be null");
name = n;

Default Field Initialization

跟 C++ 一样,当没有指明的时候,有一个默认的初值,对于数字是 0,布尔是 false,类是 null

但也一样的,不希望这么用,要是对 null invoke method 就不好了

No-Argument Constructor

前面的那都是纯语言级的 default,我们通常会用的 default 还是自己定义的,不提供参数的构造函数

When the Default Constructor Valid

跟 C++ 很像,当我们确实是什么都没提供的时候,语言级会给我们生成一个

但是当我们自己构造了一个的时候,就不会给我们自己生成了

Explicit Field Initialization

就是给 instance fields 来一个内部的 initial state (field initializers/in-class initializers)

⚠️ 并非一定要是 constant value,也可以是一个 method
⚠️ 并且调用构造函数的时候,还是先运行 in-class initializers

Calling Another Constructor

如果在当前的构造函数里第一句话是 this(...) 那就是 call another constructor 了

public Employee(double s) {
	// calls Employee(String, double)
	this("Employee #" + nextId, s);
	nextId++; 
}

vs. Delegating Constructors in C++

书中说:“However, in C++ it is not possible for one constructor to call another.”这个要怎么看呢

我想是这样的,因为 C++ 有 initializer list 的机制,在 construct 中它区分 initial 和 assign,当运行到 block 中是,构造已经结束了

而 Java 不是这样的,经验证,block 中也可 “assign” to constant

Initialization Blocks

第三种方法来初始化,就是只是在 class 中加入一个 block {...}。blocks 里直接用变量名字就可以了

当构造函数被调用的时候,它运行在构造函数 body 之前 (换句话说,如果没有构造函数被调用,就不会运行 initialization blocks。而且后面会说,static blocks behave differently)

⚠️ 另外,它允许 set 那些尚未出现的 fields,但是不允许在 block 中调用它

Static Initialization Blocks

对 block 加上 static 修饰即可

Static initialization occurs when the class is first loaded.


介绍了这么多的构造的方法,但到底当一个构造方法被 invoke 的时候,发生了怎样的过程

  1. 先看看第一行是不是在叫别的构造方法,如果是,那就去执行别的构造方法
  2. 否则的话
    1. 语言级给一个 default 值
    2. field initializers 和 initialization blocks 按照 class declaration 中出现的顺序依次执行
  3. 最终才是把整个构造方法的 body 执行了

一级标题

二级

加粗加斜