学科分类
目录
Java基础

匿名内部类

在Java中调用某个方法时,如果该方法的参数是一个接口类型,除了可以传入一个参数接口实现类,还可以使用匿名内部类实现接口来作为该方法的参数。匿名内部类其实就是没有名称的内部类,在调用包含有接口类型参数的方法时,通常为了简化代码,不会创建一个接口的实现类作为方法参数传入,而是直接通过匿名内部类的形式传入一个接口类型参数,在匿名内部类中直接完成方法的实现。

创建匿名内部类的基本语法格式如下:

new 父接口(){
  // 匿名内部类实现部分
}

接下来通过一个案例来学习匿名内部类的定义和使用,如文件1所示。

文件1 Example21.java

 1    // 定义动物类接口
 2    interface Animal { 
 3        void shout(); 
 4    }
 5    public class Example21{
 6        public static void main(String[] args) {
 7              String name = "小花"; 
 8              // 定义匿名内部类作为参数传递给animalShout()方法
 9            animalShout(new Animal() {
 10                   // 实现shout()方法
 11                 public void shout() {
 12                       // JDK 8开始,局部内部类、匿名内部类可以访问非final的局部变量
 13                    System.out.println(name+"喵喵...");
 14                }
 15            });
 16        }
 17         //定义静态方法animalShout(),接收接口类型参数
 18        public static void animalShout(Animal an) {
 19            an.shout(); // 调用传入对象an的shout()方法
 20        }
 21    }

运行结果如图1所示。

图1 运行结果

文件1中,调用animalShout(Animal an)方法时需要一个Animal接口类型的参数,在第9~15行代码就使用了匿名内部类方式实现Animal接口并作为参数传入。

需要注意的是,在文件1中的匿名内部中类访问了局部变量name,而局部变量name并没有使用final修饰符修饰,程序也没有报错,这是JDK 8开始的新特性,允许在局部内部类、匿名内部类中访问非final修饰的局部变量,而在JDK 8之前,局部变量前必须加final修饰符,否则程序编译报错。

对于初学者而言,可能会觉得匿名内部类的写法比较难理解,接下来分两步来介绍匿名内部类的编写,具体如下:

1.在调用animalShout()方法时,在方法的参数位置写上new Animal(){},这相当于创建了一个实例对象,并将对象作为参数传给animalShout()方法。在new Animal()后面有一对大括号,表示创建的对象为Animal的子类实例,该子类是匿名的。具体代码如下所示:

animalShout(new Animal(){});

2.在大括号中编写匿名子类的实现代码,具体如下所示:

animalShout(new Animal() 
{
  public void shout() {
​    System.out.println(name+"喵喵...");
  }
});

至此便完成了匿名内部类的编写。对于初学者而言不要求完全掌握这种写法,只需尽量理解语法就可以了。

点击此处
隐藏目录