P159 第二个注意框里,有关代码块的描述如下:
实际上初始化块是一个假象,使用 Javac 命令编译 Java 类后,该 Java 类中的初始化 一: 块会消失---初始化块中代码会被"还原"到每个构造器中,且位于构造器所有代码的 南 前面 。
然后经过代码检验,发现此处的描述初始化块中代码会被"还原"到每个构造器中
有误,测试代码如下:
public class InitializeDemo {
private String name;
private int age;
{
this.name = "william";
this.age = 10;
}
public InitializeDemo() {
}
public static void main(String[] args) {
InitializeDemo demo = new InitializeDemo();
System.out.println(demo.getName());
System.out.println(demo.getAge());
}
// 省略getter setter
}
编译后的class
文件中的代码经过反编译后,为
public class InitializeDemo {
private String name = "william";
private int age = 10;
public InitializeDemo() {
}
public static void main(String[] args) {
InitializeDemo demo = new InitializeDemo();
System.out.println(demo.getName());
System.out.println(demo.getAge());
}
// 省略getter setter
}
发现编译后的代码块中的内容,并未还原到构造器中,而是添加到了成员变量中。
那么,什么情况下,才会将代码块中的定义还原到构造器中呢?如下测试:
public class InitializeDemo {
private String name;
private int age;
{
setName("william");
setAge(10);
}
public InitializeDemo() {
}
// getter setter 等其他代码
}
此时编译后的class
文件为:
public class InitializeDemo {
private String name;
private int age;
public InitializeDemo() {
this.setName("william");
this.setAge(10);
}
public static void main(String[] args) {
InitializeDemo demo = new InitializeDemo();
System.out.println(demo.getName());
System.out.println(demo.getAge());
}
// getter setter 等其他代码
}
此时的变量初始化就被编译到了构造器中了。
其原因可通过类初始化过程解释。但是书中并未指明这两种方式的区别,笼统的按第二种方式来解释,可见不太严谨。
网友评论