I am learning the " Initialization of Classes and Interfaces", and it says "T is a top-level class, and an assert statement lexically nested within T is executed." Could any one tell me what does "T is a top-level class, and an assert statement lexically nested within T is executed." mean by a example?
This sentence is from JLS, and original text is like this :
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
- T is a class and an instance of T is created.
- T is a class and a static method declared by T is invoked.
- A static field declared by T is assigned.
- A static field declared by T is used and the field is not a constant variable (§4.12.4).
- T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
An assertion is a statement in the JavaTM programming language that enables you to test your assumptions about your program. For example, if you write a method that calculates the speed of a particle, you might assert that the calculated speed is less than the speed of light.
AssertEquals, AssertTrue, and AssertFalse methods are the most commonly used assertions in selenium. Generally assertions verifies whether the application is same or not when we check with our expectation. Selenium assertions are of three types. In the above syntax it returns Result , if the condition True.
This is a top level class:
class TopLevel {
...
}
This is an assert statement:
assert( condition );
where condition
is some boolean expression.
A is lexically nested into B, if it occurs inside the curly braces of B's definition. For example, fields, methods, static blocks are lexically nested in a class definition. Statements are lexically nested in methods or static blocks. Local definitions are nested in methods or blocks, that are itself nested in methods.
Hence an assert statement that is lexically nested in a top level class could be:
class A {
static {
assert ( 2+2 == 4 );
}
}
I can give a partial explanation to it. It refers to enabling/disabling assertion. Assertion is enabled by -ea
vm argument.
An important point about assert
is:
An assert statement that is executed before its class has completed initialization is enabled.
Suppose -ea
is not given and you run the below code:
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"));
}
}
In the above example when b
is initialized, Java guarantees that before line(a)
is called, the assertion is disabled (i.e. line(a) is not executed at all). Because assert enable/disable is a part of class initalization, hence it is mentioned in your shown statement in question.
The reason, why top-level class is mentioned and not every other class is this. More detailed behavior here:
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"));
}
}
Even -ea
flag is not used, still it throws an AssertionException
. Here is what happens:
true
at this stage as Bar
is still not completely initializedBar
calls Baz.testAsserts()
. The assert is still enabled (remember disabling assertion has got to do with class initialization and Bar is still not completely initialized). Now Baz.testAsserts() throws AssertionException
.Above is a loop hole. JLS only guarantees that before executing any assert
in Top level class, it will disable/enable (as whatever vm argument is given) it. But if it is not a top level class, then the behavior depends on the initialization of top-level class. To explain this, see this:
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"));
}
}
This prints Asserts disabled Asserts disabled
as Bar
is well initialized. Bar
initialization disables assert
for the class and hence for Baz
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With