Anonymous Inner classes and Final modifier [duplic

2020-02-14 02:31发布

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.

标签: java
3条回答
闹够了就滚
2楼-- · 2020-02-14 02:33

JLS 15.9.5 "...implicitly final"... But that is not "final", what is meant is that you just can't extend an anonymous class. There is no syntactic construction for this, but the class is not marked as final.

查看更多
家丑人穷心不美
3楼-- · 2020-02-14 02:54

I agree this may be considered a bug, given that other cases in the JLS exhibit a different behavior. Case in point is an interface: As per section 9.1.1.1:

Every interface is implicitly abstract.

And when running the below:

interface X {
    void foo();
}

public static void main(String arg[]) {
    System.out.println(Modifier.isAbstract(X.class.getModifiers()));
}

It returns true.

Another example is an enum where the JLS specifies:

An enum declaration is implicitly final unless it contains at least one enum constant that has a class body

And the below example is perfectly aligned with it.

enum X {

}

public static void main(String arg[]) {
    System.out.println(Modifier.isFinal(X.class.getModifiers()));  // true
}
查看更多
太酷不给撩
4楼-- · 2020-02-14 03:00

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.

查看更多
登录 后发表回答