让我们先来看两个类:Base和Derived类。注意其中的whenAmISet成员变量,和方法preProcess()。

情景1:(子类无构造方法)

class Base {
Base() {
preProcess();
} void preProcess() {
}
} class Derived extends Base {
public String whenAmISet = "set when declared"; void preProcess() {
whenAmISet = "set in preProcess()";
}
} public class StaticTest {
public static void main(String[] args) {
Derived d = new Derived();
System.out.println(d.whenAmISet);
}
}

当.java源代码转换成一个.class文件后,其转换成类似下面的等价代码:

class Base {
Base() {
preProcess();
} void preProcess() {
}
} class Derived extends Base {
public String whenAmISet; {whenAmISet = "set when declared";} void preProcess() {
whenAmISet = "set in preProcess()";
}
} public class StaticTest {
public static void main(String[] args) {
Derived d = new Derived();
System.out.println(d.whenAmISet);
}
}

输出结果是: set when declared

情景2:(子类添加了构造方法)

class Base {
Base() {
preProcess();
} void preProcess() {
}
} class Derived extends Base {
public String whenAmISet = "set when declared"; public Derived() {
whenAmISet = "set in constructor";
} void preProcess() {
whenAmISet = "set in preProcess()";
}
} public class StaticTest {
public static void main(String[] args) {
Derived d = new Derived();
System.out.println(d.whenAmISet);
}
}

当.java源代码转换成一个.class文件后,其转换成类似下面的等价代码:

class Base {
Base() {
preProcess();
} void preProcess() {
}
} class Derived extends Base {
public String whenAmISet; public Derived() {
whenAmISet = "set when declared";
whenAmISet = "set in constructor";
} void preProcess() {
whenAmISet = "set in preProcess()";
}
} public class StaticTest {
public static void main(String[] args) {
Derived d = new Derived();
System.out.println(d.whenAmISet);
}
}

输出结果为:set in constructor

情景3:(赋值的细节)

public class Singleton {

    private static Singleton mInstance = new Singleton();  // 位置1
public static int counter1;
public static int counter2 = 0; private Singleton() {
counter1++;
counter2++;
} public static Singleton getInstantce() {
return mInstance;
} public static void main(String[] args) {
Singleton singleton = Singleton.getInstantce();
System.out.println("counter1: " + singleton.counter1);
System.out.println("counter2: " + singleton.counter2);
}
}

当.java源代码转换成一个.class文件后,其转换成类似下面的等价代码:

public class Singleton {

    private static Singleton mInstance;
public static int counter1;
public static int counter2; static {
mInstance = new Singleton();
counter2 = 0;
} private Singleton() {
counter1++;
counter2++;
} public static Singleton getInstantce() {
return mInstance;
} public static void main(String[] args) {
Singleton singleton = Singleton.getInstantce();
System.out.println("counter1: " + singleton.counter1);
System.out.println("counter2: " + singleton.counter2);
}
}

同理,以下代码的最终输出结果为:counter1: 1  counter2: 1

public class Singleton {

    public static int counter1;
public static int counter2 = 0;
private static Singleton mInstance = new Singleton(); // 位置2 private Singleton() {
counter1++;
counter2++;
} public static Singleton getInstantce() {
return mInstance;
} public static void main(String[] args) { Singleton singleton = Singleton.getInstantce();
System.out.println("counter1: " + singleton.counter1);
System.out.println("counter2: " + singleton.counter2);
}
}

原因分析:

  1. 陈皓博客
  2. Java Tutor - Visualize Java code execution to learn Java online (also visualize PythonJavaJavaScriptTypeScriptRubyC, and C++ code)
05-07 12:32
查看更多