匿名内部类和最终修饰符

时间:2017-06-29 06:25:00

标签: java

我的理解正确anonymous classes始终是final

JLS 15.9.5

中特别提到了这一点

但是,当我运行以下代码以检查它是否显示Inner类不是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());
        }
    }
}

以上程序的输出是:

It is not final 0

请清除我的疑问,因为我无法理解这种行为。

3 个答案:

答案 0 :(得分:3)

我同意这可能被视为一个错误,因为JLS中的其他情况表现出不同的行为。一个典型的例子是界面:按照section 9.1.1.1

  

每个界面都隐式abstract

当运行以下内容时:

interface X {
    void foo();
}

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

它返回true。

另一个例子是枚举the JLS specifies

  

枚举声明是隐式final,除非它包含至少一个具有类主体的枚举常量

以下示例与之完全一致。

enum X {

}

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

答案 1 :(得分:1)

明确是源代码中编写的内容。因此,如果某些内容被声明为public final class,则表示该类显式为最终

隐式是未在源代码中写下的内容,但是在某个构造的上下文中或基于语言规则,元素的行为与使用指定的修饰符声明的行为相同

例如,声明enum中的关键字enum SomeEnum { }会导致SomeEnum成为final,因为语言规则会规定它。其效果与关键字final的效果相同。

隐式最终的匿名类的示例是因为不存在覆盖匿名类的语言构造。所以它表现得好像是final。我认为“有效”这个词在这里更好。

但是,你不能根据反射的呈现方式做出假设。请考虑以下代码段:

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()));
    }
}

结果如下:

abstract static interface
abstract static interface
abstract static
static final

interfaceabstract interface都被视为抽象接口。它们也被反射视为静态的。显然,在解析和编译Java源代码的过程中,可以删除或添加一些修饰符。

答案 2 :(得分:0)

JLS 15.9.5&#34; ...隐含最终&#34; ...但这不是&#34;最终&#34;,这意味着您无法扩展匿名类。这没有语法结构,但是这个类没有被标记为final。