Anonymous Inner classes and Final modifier

Joker :

To my understand correctly anonymous classes are always final:

This has been mentioned specifically in JLS 15.9.5

However, when i run the following code to check that it is showing that Inner class is not final.

    public class Test{
    static class A<T> {
    }
    public static void main(String arg[]) {
        A<Integer> obj = new A() {
        };
        if ((obj.getClass().getModifiers() & Modifier.FINAL) != 0) {
            System.out.println("It is a final  " + obj.getClass().getModifiers());
        } else {
            System.out.println("It is not final " + obj.getClass().getModifiers());
        }
    }
}

Output of above program is :

It is not final 0

Please clear my doubt as i am not able to understand this behavior.

MC Emperor :

Explicit is something what is written in the source code. So, if something is declared as public final class, it means that the class is explicitly final.

Implicit is something that is not written down in the source code, but that in the context of a certain construct or based on the language rules, an element behaves as it were declared with the specified modifier.

For example, the keyword enum in the declaration enum SomeEnum { } causes SomeEnum to be final, because the language rules prescribe it. Its effect is the same as the effect of the keyword final.

The example of an anonymous class being implicitly final is because no language construct exists to override an anonymous class. So it behaves as if it were final. I think the word "effectively" is better here.


However, you cannot make assumptions based on how reflection presents things. Consider the following snippet:

public class Test {
    interface SomeInterface { }
    abstract interface SomeAbstractInterface { }
    static abstract class SomeAbstractClass { }
    enum SomeEnum { }

    public static void main(String arg[]) {
        System.out.println(Modifier.toString(SomeInterface.class.getModifiers()));
        System.out.println(Modifier.toString(SomeAbstractInterface.class.getModifiers()));
        System.out.println(Modifier.toString(SomeAbstractClass.class.getModifiers()));
        System.out.println(Modifier.toString(SomeEnum.class.getModifiers()));
    }
}

The result is this:

abstract static interface
abstract static interface
abstract static
static final

Both interface and abstract interface are considered an abstract interface. They are also considered static by reflection. Apparently, in the process of parsing and compiling the Java source code, some modifiers could be removed or added.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=461564&siteId=1