Java 中的匿名成员类



关于匿名类的主题,Oracle 文档指出......

它们

类似于本地类,只是它们没有名称。如果只需要使用一次本地类,请使用它们

现在,鉴于局部类(据我所知)是在方法(或其他一些本地构造)中定义的类,如下所示......(其中"MyInterface"是具有抽象"测试"方法的接口)

public void localTest(){
MyInterface mi = new MyInterface(){
@Override
public void test(){System.out.println("test");};
};
}

以上是可以的,属于上面的定义,但是,我也可以定义以下内容...

class MyClass{
MyInterface mi = new MyInterface(){
@Override
public void test(){System.out.println("test");};
};
}

这不在方法中,因此不是"本地"类,因此不属于上述定义。 有没有任何地方我可以读到这些类型的匿名类(匿名成员类,如果你愿意的话)。如果不是定义的匿名类,它们到底是什么?

您显示的两个示例都是匿名类。真正的本地类是方法(或其他代码块)中的类定义,具有实际名称(因此,不是匿名的)。给定您的示例,等效的本地类将是:

public void localTest(){
class LocalClass implements MyInterface {
@Override
public void test(){
System.out.println("test");
}
}
MyInterface mi = new LocalClass();
}

在我看来,你几乎不需要本地课程。我想我只尝试过一次使用它,只有在我掌握了我实际需要的东西时才快速重构它。

本地类和匿名类之间最重要的区别是,您可以在同一方法中重用本地类(即在同一方法中创建多个实例;而无需诉诸循环或 lambda)。

此外,由于您实际上具有类定义,因此还可以定义和调用未在接口或超类中定义的方法。在Java 10和引入var之前,匿名类无法做到这一点。

其他细微的区别是本地类可以是抽象的或最终的,局部类可以扩展(并由其他本地类扩展),而匿名类不是最终的,不能是抽象的,但匿名类不能由其他类扩展。

有关本地类和匿名类之间区别的更多信息,请参阅 Java 语言规范,特别是 14.3。本地类声明和 15.9.5。匿名类声明和相关部分。

局部类在这里定义为在中定义,而不是在方法中定义。您的示例仍然是一个匿名类。如果您正在学习,请注意,您实际上可以用如下所示的 lambda 表达式替换声明:

MyInterface mi = () -> System.out.println("test");

此外,匿名类仅被描述为类似于本地类,这意味着前者不一定是后者的子集。

最新更新