我正在学习"类和接口的初始化",它说"T是一个顶级类,并且在T中执行词法嵌套的断言语句." 任何人都可以告诉我"T是一个顶级类,并且执行一个词法嵌套在T中的断言语句." 举个例子?
这句话来自JLS,原文是这样的:
类或接口类型T将在第一次出现以下任何一个之前立即初始化:
- T是一个类,并且创建了T的实例.
- T是一个类,并且调用由T声明的静态方法.
- 分配由T声明的静态字段.
- 使用由T声明的静态字段,该字段不是常量变量(第4.12.4节).
- T是顶级类,并且执行在词典内嵌套在T中的断言语句(第14.10节).
我可以给它一个部分解释.它指的是启用/禁用断言.声明由-eavm参数启用.
关键assert是:
在其类完成初始化之前执行的assert语句已启用.
假设-ea未给出,您运行以下代码:
public class Q1 {
public static void main(String[] args) {
Bar b = new Bar();
}
}
class Bar {
static {
boolean enabled = false;
assert enabled = false; //line(a)
System.out.println("Asserts " +
(enabled ? "enabled" : "disabled"));
System.out.println("as");
Baz.testAsserts();
}
}
class Baz extends Bar {
static void testAsserts() {
boolean enabled = false;
assert enabled = false;
System.out.println("Asserts " +
(enabled ? "enabled" : "disabled"));
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,当b初始化时,Java保证在line(a)调用before之前,断言被禁用(即,行(a)根本不被执行).因为断言启用/禁用是类初始化的一部分,因此在您显示的声明中提到它.
原因,为什么提到顶级课而不是其他所有课都是这个.这里有更详细的行为:
public class Q1 {
public static void main(String[] args) {
Baz.testAsserts();
// Will execute after Baz is initialized.
}
}
class Bar {
static {
Baz.testAsserts();
// Will execute before Baz is initialized!
}
}
class Baz extends Bar {
static void testAsserts() {
boolean enabled = false;
assert enabled = false;
System.out.println("Asserts " +
(enabled ? "enabled" : "disabled"));
}
}
Run Code Online (Sandbox Code Playgroud)
甚至-ea没有使用旗帜,它仍然会抛出AssertionException.这是发生的事情:
true在这个阶段Bar仍未完全初始化Bar电话静态Baz.testAsserts().断言仍然被启用(记得禁用断言与类初始化有关,而Bar仍未完全初始化).现在Baz.testAsserts()抛出AssertionException.上面是一个环孔.JLS只保证在执行assert顶级类中的任何一个之前,它将禁用/启用(如同给定的任何vm参数)它.但如果它不是顶级类,那么行为取决于顶级类的初始化.要解释这一点,请看:
class Bar {
static {
//Baz.testAsserts();
boolean enabled = false;
assert enabled = false;
System.out.println("Asserts " +
(enabled ? "enabled" : "disabled"));
// Will execute before Baz is initialized!
}
}
class Baz extends Bar {
static void testAsserts() {
boolean enabled = false;
assert enabled = false;
System.out.println("Asserts " +
(enabled ? "enabled" : "disabled"));
}
}
Run Code Online (Sandbox Code Playgroud)
这打印Asserts disabled Asserts disabled得Bar很好初始化.Bar初始化禁用assert该类,因此禁用Baz.
| 归档时间: |
|
| 查看次数: |
469 次 |
| 最近记录: |