执行顺序是从超类到子类定义的,在类内,首先执行变量的静态初始化,然后执行初始化块。这给出了以下顺序:
class X {
int m = 1111; // 1st point visited
// This is X's initializer block:
{
m = m++; // 2nd point visited: m's value is not changed, read below
System.out.println(m);
}
}
class Y extends X {
// This is Y's initializer block:
{
System.out.println(methodOfY()); // 3rd and 5th point visited:
// 2220 is printed after
// methodOfY() has been evaluated
}
int methodOfY() {
return m-- + --m; // 4th point visited: m-- = 1111 (m = 1110),
// --m = 1109 (m = 1109), therefore 2220 is
// returned
}
}
public class MainClass {
public static void main(String[] args) {
Y y = new Y();
}
}
现在到前置和后置操作符。您可以“手动”实现它们1以了解它们的行为:
public class PrePostIncrement {
int value;
public PrePostIncrement(int value) {
this.value = value;
}
public int preIncrement() {
this.value = this.value + 1;
return (this.value);
}
public int postIncrement() {
int result = this.value;
this.value = this.value + 1;
return (result);
}
public static void main(String... args) {
PrePostIncrement test = new PrePostIncrement(1111);
int newValue = test.postIncrement();
System.out.println(newValue);
}
}
如您所见,postIncrement() 返回的值是1111。这将是在X 的初始化程序块中分配给m 的新值。因此,m 将具有 1112 的值,只是为了非常简短。
因为我不希望你简单地相信我,所以我写了一些代码来显示这种行为:
public class Main {
public static volatile int x = 0;
public static volatile boolean running = true;
public static void main(String... args) {
Thread observer = new Thread(() -> {
while (true) {
int x = Main.x;
System.out.println("Observer observed: " + x);
if (0 != x) {
break;
}
}
Main.running = false;
});
observer.start();
while (running) {
Main.x = Main.x++;
}
System.out.println(Main.x);
}
}
如您所见,observer 的唯一目的是打印x 的值,直到它看到x 的值为1。主线程继续执行x = x++;,直到observer 看到x 的值发生了一次变化。之后,x 的最终值将被打印出来。请注意,此程序必须在真正的多核系统上运行,否则可能会死循环。
在我的系统上,我通常会迭代一到六次 observer,直到看到更改。但是,x 的最终值将始终为“0”2。
P.S.:欢迎来到 Java 并发世界。如果要编写一个具有多个线程的应用程序,需要同时访问x,则很可能将x 定义为AtomicInteger 并使用方法int incrementAndGet()(而不是++x)和int getAndIncrement()(而不是++x)。这些方法保证x 的中间值不会被其他线程看到。
1请不要这样做。 ++i 和 i++ 是语言结构,可以由编译器高度优化。这只是为了展示他们的行为。
2即使在多核系统上,该程序也可能在无限循环中运行,但程序将终止almost surely。推理是observer 看到x 的值为0 的概率是