Java 类中变量的初始化,类内部变量/代码块的加载顺序
1. 变量的初始化方法
先不考虑继承父类和实现接口的情形,设想对一个Pet类的成员变量和静态变量进行初始化,有下列方法。
1.1 直接定义字段时赋值 or 显示字段初始化
private String name = "Lina";
private static String MasterName = "John";
1.2 调用方法进行初始化
1.2.1 调用方法赋值给变量
可以使用任何静态方法给静态变量/非静态变量赋值,也同样可以使用非静态方法给非静态变量赋值,只要方法返回的数据类型和变量的类型一致即可。
private int age = setAge();
public int setAge() {
int num = 2;
return num;
}
private static String id = setId();
public static String setId() {
String id = "X0012";
return id;
}
以上方式进行初始化本质上等同于直接赋值,只不过使用了方法的返回值代替了原本的值。
1.2.2 在非构造器的普通方法内进行初始化
变量在可以非构造器的普通方法内进行初始化,但是只有在创建对象,调用了方法之后才能真正完成初始化,而不是发生在类加载字段时。
(通常static变量不采用这种方式进行初始化,但只要使用该变量前完成了初始化,并不会影响实际使用)
private static String FatherName;
private String MotherName;
public static void setFatherName() {
FatherName = "Dog A";
}
public void setMotherName() {
FatherName = "Dog B";
}
1.3 成员变量-初始化代码块中初始化
成员变量可以在初始化代码块中初始化,初始化代码块可以定义多个。
private double height;
private double weight;
// initialization block 1
{
height = 0.5;
}
// initialization block 2
{
weight = 20;
}
注:静态变量是属于整个类的变量而不是属于某个对象的,因此不能把任何方法体内 (包括静态方法和静态代码块) 的局部变量声明为静态的。
1.4 静态变量-静态化代码块中初始化
类似地,静态变量可以在静态化代码块中初始化,静态代码块同样可以定义多个。
private static String color;
private static String sex;
// static block 1
static {
color = "Dotted";
}
// static block 2
static {
sex = "Female";
}
1.5 构造器中初始化
静态代码块和初始化代码块可以完成初始化任务,但通常情况下初始化变量的任务由构造器完成。下面初始化一下三个变量:
private String type;
private boolean healthy;
private static double price;
1.5.1 默认构造器初始化
在没有定义任何构造器时,Java会给我们自动提供一个默认的无参数构造器。
该构造器会将基本数据类型初始化为默认值,引用对象类型设置为null。
public Pet() {
this.type = null;
this.healthy = false;
this.price = 0.0;
}
但是当自主定义了一个构造器时,就不会自动提供默认构造器。没有被自定义的构造器初始化的变量将不会被初始化,除非再次定义一个无参数的构造器。如果自定义无参数的构造器,若构建对象时存在没有初始化的变量,也将自动初始化变量为默认值。
1.5.2 自定义构造器初始化
Java允许自定义多个构造器,也即重载构造器。
一个构造器可以通过this(…)调用其他的构造器,但是该语句必须位于构造器首行
public Pet(String type) {
this.type = type;
}
public Pet(String type, boolean healthy, double price) {
this(type);
this.healthy = healthy;
this.price = price;
}
- 引用对象类型的变量的初始化:
有时候,会经常碰到一个类中含有引用对象类型的变量,与基本数据类型变量相似,引用对象类型变量也同样可通过上述方法进行初始化。
现在假设有一个Toy类,而Pet类中列出了几种宠物爱玩的玩具,分别用1-6数字来代替玩具名
class Toy {
private int toolNum;
// Tool class 无参数构造器
public Toy() {
}
// Tool class 含参数构造器
public Toy(int toolNum) {
this.toolNum = toolNum;
}
}
实际情况下,很少会创造静态对象,因为静态修饰的字段被类共享。此处引入静态对象仅仅是为了演示初始化方法及变量加载顺序,无其他实际意义。
初始化对象类变量:
private static Toy toy1;
private Toy toy2;
private Toy toy3 = generateToy();
private static Tool toy4 = new Toy(