Java最高

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>看看这个课程

1.介绍

在本教程中,我们将考虑Java中的匿名类。

我们将描述如何声明和创建它们的实例。我们还将简要讨论它们的性质和局限性。

2.匿名类声明

匿名类是没有名称的内部类。因为它们没有名称,所以我们不能使用它们来创建匿名类的实例。因此,在使用时必须在单个表达式中声明和实例化匿名类。

我们可以扩展现有的类,也可以实现接口。

2.1。扩展一个类

当从一个已经存在的匿名类实例化一个匿名类时,使用以下语法:

在圆括号中,指定要扩展的类的构造函数所需要的形参:

new Book("Design Patterns") {@Override public String description() {return "Famous GoF Book .";}}

自然地,如果父类构造函数不接受实参,则应该将圆括号保留为空。

2.2。实现一个接口

也可以从接口实例化一个匿名类:

显然,Java的接口没有构造函数,所以圆括号总是空的。这是实现接口方法的唯一方法:

new Runnable() {@Override public void run(){…}}

一旦实例化了一个匿名类,就可以将该实例赋值给一个变量,以便以后在某个地方引用它。

我们可以使用Java表达式的标准语法来做到这一点:

= new Runnable() {@Override public void run(){…}};

正如我们之前提到的,匿名类声明是一个表达式,因此它必须是语句的一部分。这就解释了为什么我们要在语句的末尾加上分号。

显然,如果以内联方式创建实例,可以避免将实例赋值给变量:

List<可运行> actions = new ArrayList<可运行>();行动。add(new Runnable() {@Override public void run(){…}});

我们应该非常小心地使用这种语法,因为它很容易损害代码的可读性,特别是当实现run ()方法需要很多空间。

3.匿名类属性

与通常的顶级类相比,使用匿名类有一些特殊之处。在这里,我们简单地谈谈最实际的问题。要获得最精确和最新的信息,我们可以随时查看Java语言规范

3.1。构造函数

匿名类的语法不允许我们让它们实现多个接口。在施工期间,匿名类可能只存在一个实例。因此,它们绝不可能是抽象的。因为他们没有名字,我们不能扩展他们。出于同样的原因,匿名类不能显式声明构造函数。

事实上,由于以下原因,构造函数的缺失并不代表任何问题:

  1. 我们在声明匿名类实例的同时创建它们
  2. 从匿名类实例中,我们可以访问局部变量和外围类的成员

3.2。静态成员

除了常量之外,匿名类不能有任何静态成员。

例如,这不能编译:

new Runnable() {static final int x = 0;静态int y = 0;/ /编译错误!@Override public void run(){…}};

相反,我们会得到以下错误:

字段y不能在非静态内部类型中声明为静态,除非使用常量表达式初始化

3.3。变量的范围

匿名类捕获在声明类的块范围内的局部变量:

Int count = 1;@Override public void run() {System.out. Runnable action = new Runnable() {@Override public void run() {println("Runnable with capture variables: " + count);}};

正如我们看到的,局部变量行动在同一个块中定义。因此,我们可以访问从类声明内部。

注意,为了能够使用局部变量,它们必须是有效的final。因为JDK 8,我们不再需要用关键字声明变量最后。然而,这些变量必须是最后。否则,就会出现编译错误:

从内部类引用的局部变量必须是final或有效final

为了让编译器判定一个变量在代码中实际上是不可变的,我们应该只在一个地方给它赋值。我们可能会在文章中找到更多关于有效最终变量的信息"金宝搏官网188be为什么lambda中使用的局部变量必须是Final或有效Final?

让我们把它作为每个内部类,匿名类可以访问其外围类的所有成员

4.匿名类用例

可能有各种各样的匿名类应用程序。让我们探讨一些可能的用例。

4.1。类层次结构和封装

我们应该在一般用例中使用内部类,在非常特定的用例中使用匿名类,以便在我们的应用程序中实现更干净的类层次结构。当使用内部类时,我们可以对外围类的数据进行更精细的封装。如果我们在顶层类中定义内部类的功能,那么外围类应该有公共一些成员的可见性。自然地,有些情况下它并不被欣赏,甚至不被接受。

4.2。清洁项目结构

当必须修改时,我们通常使用匿名类在飞行中某些类的方法的实现。在这种情况下,我们可以避免添加new* . java文件到项目,以便定义顶级类。如果这个顶级类只被使用一次,这尤其正确。

4.3。UI事件监听器

在具有图形界面的应用程序中,匿名类最常见的用法是创建各种事件监听器。例如,在以下代码片段中:

按钮。addActionListener(new ActionListener() {public void actionPerformed(ActionEvent){…}}

我们创建一个实现接口的匿名类的实例ActionListener。它的actionPerformed方法在用户单击按钮时触发。

从Java 8开始,lambda表达式这似乎是一种更可取的方式。

5.一般的照片

我们上面考虑的匿名类只是一种特殊情况嵌套类。一般来说,嵌套类是在另一个类或接口中声明的类:

在图中,我们可以看到匿名类当地的非静态的成员的形成了所谓的内部类。在一起静态成员类,它们形成了嵌套类。

6.结论

在本文中,我们考虑了Java匿名类的各个方面。我们也描述了嵌套类的一般层次结构。

与往常一样,完整的代码是可用的在我们的GitHub仓库

Java底部

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>看看这个课程
2评论
最古老的
最新的
内联反馈
查看所有评论
对这篇文章的评论关闭!