欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

匿名内部类的使用以及Java8引入的Lambda表达式对匿名内部类的简化

程序员文章站 2022-10-03 14:33:08
文章内容输出来源:拉勾教育大数据训练营;内部类1.什么是内部类?当一个类的定义出现在另一个类的类体中时,这个类叫做内部类(Inner),内部类所在的类叫外部类(Outer)。2.特殊之处内部类和外部类都可以互相使用对方的私有成员。3.内部类的实际作用当一个类存在的价值仅仅是为某一类单独服务时,就可以将该类定义为内部类,这样可以隐藏该类的实现细节;并且可以方便的访问外部类的私有成员而不再需要提供公有的get和set方法。4.有哪些内部类?普通/成员内部类、静态内部类、局部/方法内部类、匿名...

文章内容输出来源:拉勾教育大数据训练营;


内部类

1.什么是内部类?

当一个类的定义出现在另一个类的类体中时,这个类叫做内部类(Inner),内部类所在的类叫外部类(Outer)。

2.特殊之处

内部类和外部类都可以互相使用对方的私有成员。

3.内部类的实际作用

当一个类存在的价值仅仅是为某一类单独服务时,就可以将该类定义为内部类,这样可以隐藏该类的实现细节;并且可以方便的访问外部类的私有成员而不再需要提供公有的get和set方法。

4.有哪些内部类?

普通/成员内部类、静态内部类、局部/方法内部类、匿名内部类。

了解了内部类的基本概念后,我们本篇文章重点介绍内部类中的
匿名内部类


匿名内部类

通俗的说,匿名内部类就是没有名字的内部类。

什么时候用匿名内部类?

假如我们只需要创建某个类的的一个对象,那么就可以考虑使用。

就我目前接触到的内容而言,我感觉匿名内部类多用在多态的使用场合1(即通过方法的参数传递形成多态,在传递实参的时候使用匿名内部类的语法格式得到接口/类类型的引用),关于多态的使用场合介绍在我的上一篇文章 Java三大特性封装、继承、多态 中有详细说明。

匿名内部类的格式

接口/父类类型 引用变量名 = new 接口/父类类型( ){ 方法的重写 };

注意花括号后的分号不能丢。

下面分享一个我最近遇到的使用匿名内部类的实例。

实例:获取目录下满足筛选器的所有内容

File[ ] listFiles(FileFilter filter)

方法说明:该方法是获取目录下满足筛选器的所有内容;

FileFilter是个接口,我们通过匿名内部类的形式来获取一个FileFilter的对象作为实参传入。

代码实现:

import java.io.File;
import java.io.FileFilter;

public class AnonymityTest {

    public static void main(String[] args) {
		
		// 构造一个指向E盘下的对象 
        File file = new File("E:/");
		// 匿名内部类的方式构造一个FileFilter筛选器对象
		// 得到以BD结尾的所有文件或目录
        FileFilter filter = new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.getName().endsWith("BD");
            }
        };
		// 将构造的filter对象作为实参传入
        File[] files = file.listFiles(filter);
        // 打印所有满足要求的文件或目录名
        for (File f : files) {
            System.out.println(f);
        }
    }
}

通过上述代码我们可以来分析使用匿名内部类的好处:

不使用匿名内部类的时候,我们要给listFiles方法传参时,要先定义一个实现类去实现FileFilter接口,然后创建一个这个实现类的对象作为实参传入。

使用匿名内部类时,我们不需要再定义类,直接使用匿名内部类的格式就可以得到一个FileFilter接口的实现类对象,代码相对简化了一部分。


Lambda表达式

Lambda表达式是Java8引入的新特性,是对匿名内部类写法的代码简化。

Lambda表达式的格式

接口/父类类型 引用变量名 = ( 重写方法的参数列表 ) -> { 方法体 };

使用Lambda表达式对上述案例再次简化
import java.io.File;
import java.io.FileFilter;

public class AnonymityTest {

    public static void main(String[] args) {
		
		// 构造一个指向E盘下的对象 
        File file = new File("E:/");
		// Lambda表达式的方式构造一个FileFilter筛选器对象
		// 得到以BD结尾的所有文件或目录
        FileFilter filter = (File file1) -> {return file1.getName().endsWith("BD");};
		// 将构造的filter对象作为实参传入
        File[] files = file.listFiles(filter);
        // 打印所有满足要求的文件或目录名
        for (File f : files) {
            System.out.println(f);
        }
    }
}

一个问题:上述Lambda表达式中参数列表那里写File file会报错,提示file已经被定义,而用匿名内部类去这样写的时候不会报错。说明它们的实现原理是不同的,具体它们底层是如何实现的还未探究。。。

此外,还要注意一点,Lambda表达式只能简化接口形式的匿名内部类。
即只能简化接口 引用变量名 = new 接口( ){ 方法的重写 };这种形式的匿名内部类,而对于父类类型 引用变量名 = new 父类类型( ){ 方法的重写 };这种形式的匿名内部类,写成Lambda表达式的格式时会提示Target type of a lambda conversion must be an interface,不能用用Lambda表达式简化。

本文地址:https://blog.csdn.net/weixin_43102071/article/details/107675472