Java的匿名类、匿名函数与方法引用

Java的匿名类、匿名函数与方法引用

一、前言

从我接触 Java 伊始,就见过了很多匿名函数java 匿名类,最典型的是 Java 的多线程java 匿名类,写法如下:

new Thread(() -> {
    for (int i = 0; i < 100; i++) {
        System.out.println(i);
    }
}).start();

起初我十分不理解这是一种什么写法,经过查询也只知道这是一种叫 函数的东西,看了很多文章之后也没能很好的理解。现在是终于搞懂了,所以写一篇总结来帮助我梳理一下相关知识。

二、匿名类与匿名函数

匿名类,顾名思义就是没有类名字的类。匿名函数相对应的就是没有名字的函数。因为没有名字,两者都适用于定义一个不需要被重用的类或者方法的场景。其实这两者是共通的。在我的理解里,匿名函数是对匿名内部类的进一步简化抽象。对于匿名类来说,一般都是需要实现多个方法时使用的。例子如下:

interface Pet {
    String getName();
    String getAge();
}
class PetShop {
    static void sell (Pet pet) {
        System.out.println("Pet name is " + pet.getName()
                + "nPet age is " + pet.getAge());
    }
    public static void main(String[] args) {
        PetShop.sell(new Pet() {
            @Override
            public String getName() {
                return "Ruby";
            }
            @Override
            public String getAge() {
                return "10";
            }
        });
    }
}

java 匿名类

可以看到,在这个例子中, 这个类的 sell 方法会用到 Pet 接口的实现类,但是这个实现类只需要使用一次,不需要复用(因为这里面逻辑是出售)。在这种情况下就可以使用匿名类,在不定义类名的情况下实现两个方法即可。

但是在只需要实现接口一个方法的情况下,我们可以简化上面的使用方式,使用匿名函数,也就是 表达式:

interface Pet {
    String getName();
}
class PetShop {
    static void sell (Pet pet) {
        System.out.println("Pet name is " + pet.getName());
    }
    public static void main(String[] args) {
        PetShop.sell(() -> "Ruby");
    }
}

使用了 表达式之后一下子少了很多行代码。 表达式分为两部分,用->分开,左边是方法的参数,右边是返回值。相比匿名类的实现方式,删除了接口信息和方法名。其实仔细想想就知道为什么这些东西都能删掉。接口信息在 sell 方法中有定义,方法调用也有,并且由于只有一种方法需要实现,所以根本不需要纠结,只需要把 右边的返回值赋值给 pet.()就好了。

再用 接口举个例子:

List integers = new ArrayList(Arrays.asList(5, 4, 3, 2, 1, 0));
Comparator comparator1 = new Comparator() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1.compareTo(o2);
    }
};
Comparator comparator2 = (o1, o2) -> o1 > o2 ? 1 : 0;
integers.sort(comparator1);
integers.sort(comparator2);

中需要实现 方法,而 sort 里面需要传入一个 实例,最终实例的 方法会被调用,来决定排序的规则。可以用匿名类和匿名函数两种方式来实现,这种情况下自然是 表达式更简洁了。但是说实话对于不了解的人来说, 表达式还是有着一定的理解门槛的。

三、方法引用

java 匿名类

匿名函数 表达式其实仍然不是最简化的调用方法,因为我们可以发现参数有可能也可以省略,这就是所谓的方法引用,还是拿 举例子:

Comparator comparator3 = Integer::compareTo;
integers.sort(comparator3);

可以看到java 匿名类,方法引用省去了参数,直接使用类::方法的形式实现匿名函数的效果。这里的方法可以是静态方法,也可以是实例方法(就如同这个例子一样,第一个参数是实例方法的调用者,第二个参数是实例函数的参数),甚至类也可以是一个实例,非常灵活。

对于具体参数如何调用的,可以参考以下三句话:

成员方法的方法签名,前面会追加 this 的类型。静态方法的方法签名Java的匿名类、匿名函数与方法引用,因为没有 this, 不会追加任何东西。当 :: 前是一个实例时,这个实例会作为第一个参数给绑定到目标方法签名上。

但是对于一些不带参数的方法调用,方法引用也不太好用Java的匿名类、匿名函数与方法引用,比如文章刚开始的多线程例子就没法使用方法引用的方式表达。

四、总结

可以看出,匿名类、匿名函数与方法引用三者抽象程度越来越高,适用范围越来越小。经过这一番探究,现在再回头看文章第一部分的多线程代码就十分简单了:start()调用会调用 表达式的右边部分(实际上是 run 方法),所以这个线程会打印 0-99 的数字。后续打算再写一篇关于 源码的分析,敬请期待。

公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299

资源库 - 资源分享下载网 » Java的匿名类、匿名函数与方法引用

常见问题FAQ

关于资源售价和售后服务的说明?
本站所有资源的标价均为本站收集资源的辛苦费,不代表资源本身的价值。软件是高智慧高价值的商品,不可能是白菜价。本站资源标价只是赞助费用,收取的赞助费仅用来维持本站的日常运营!毕竟收集整理资料需要投入云计算资源和站长大量的精力。
代码有没有售后服务和技术支持?
由于代码的运行具有不可预见性,本站不保证代码完整可运行,不提供技术支持和售后服务。 本站原创代码都是站长自己开发的,可以有偿提供技术支持服务。 网站里标明【亲测】的代码都是站长亲测过的,其他的代码由于精力有限,没有一一测试,不能保证代码就一定能够使用,更没有技术支持服务,下载前请自行斟酌。
有没有搭建服务?
由于搭建服务比较费时费力,所以本站除了原创代码外均不提供搭建服务。本站分享代码纯属兴趣爱好,不以盈利为目的,请勿咨询有没有搭建服务,谢谢理解。
链接地址失效了怎么办?
请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。
关于解压密码
本站资源一般都没有加密,如果发现需要解压密码的,那么就输入 hao.35dc.com 试试。

发表评论

资源库,由老程序员细心甄别、精心筛选,只为提供优质的源码资源

关于我们 联系我们