What does "T is a top-level class, and an assert statement lexically nested within T is executed." mean?

java

Solution

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:

- Q1.main is called

- Q1.main calls Baz.testAsserts.

- Because Baz extends Bar and Bar is not initialized, as per JLS it tries to initialize Bar

- static block of Bar is called. Remember assert statement is enabled before its class has completed initialization or assert is called (which ever happens first). Which in this case is `true` at this stage as `Bar` is still not completely initialized

- static of `Bar` 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`.

Problem

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.

Original source