匿名内部类和最终修饰符

据我所知, anonymous classes总是final

这已在JLS 15.9.5中具体提到

但是,当我运行以下代码来检查它是否显示Inner类不是final

  public class Test{ static class A { } public static void main(String arg[]) { A 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 

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

显式是源代码中编写的内容。 因此,如果某些内容被声明为public final class ,则意味着该类显式为final

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

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

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


但是,您无法根据reflection的呈现方式做出假设。 请考虑以下代码段:

 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都被视为抽象接口。 它们也被reflection视为静态的。 显然,在解析和编译Java源代码的过程中,可以删除或添加一些修饰符。

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

每个接口都是隐式abstract

并在运行以下时:

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

它返回true。

另一个例子是一个枚举,其中JLS指定 :

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

以下示例与它完全一致。

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

JLS 15.9.5“……含蓄地最终”……但这不是“最终的”,这意味着你不能扩展匿名类。 这没有语法结构,但是类没有标记为final。