私はそれについて部分的な説明をすることができます。アサーションの有効化/無効化を指します。アサーションは、-ea
vm 引数によって有効になります。
重要な点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"));
}
}
が初期化される上記の例でb
は、Java は before が呼び出されることを保証しline(a)
、アサーションは無効になります (つまり、line(a) はまったく実行されません)。assert enable/disable はクラスの初期化の一部であるため、問題のステートメントに記載されています。
トップレベルのクラスが言及され、他のすべてのクラスが this であるとは限らない理由。ここでのより詳細な動作:
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"));
}
}
フラグも-ea
使用されていませんが、それでも . がスローされAssertionException
ます。何が起こるかは次のとおりです。
- Q1.main が呼び出されます
- Q1.main は Baz.testAsserts を呼び出します。
- Baz は Bar を拡張し、Bar は初期化されていないため、JLS に従って Bar を初期化しようとします。
- Bar の静的ブロックが呼び出されます。assert ステートメントは、そのクラスの初期化が完了する前、または assert が呼び出される前 (いずれか早い方) に有効になることに注意してください。この場合、まだ完全に初期化されていないため
true
、この段階にありますBar
Bar
呼び出しの静的Baz.testAsserts()
。アサートはまだ有効です (アサーションの無効化はクラスの初期化と関係があり、Bar はまだ完全に初期化されていないことに注意してください)。Baz.testAsserts() が をスローするようになりAssertionException
ました。
上は抜け穴です。assert
JLS は、最上位クラスで実行する前に、それを無効/有効にすることのみを保証します (どのような 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"));
}
}
これは適切に初期化されたものとして出力Asserts disabled Asserts disabled
されBar
ます。クラスのBar
初期化が無効になり、したがって が無効になります。assert
Baz