Java :: 双冒号使用

試著忘記壹切 提交于 2020-02-05 17:19:28

英文:double colon,双冒号(::)运算符在Java 8中被用作方法引用(method reference),方法引用是与lambda表达式相关的一个重要特性。它提供了一种不执行方法的方法。为此,方法引用需要由兼容的函数接口组成的目标类型上下文。

    Method References
    You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
    参考oracle官网

您使用lambda表达式来创建匿名方法。然而,有时lambda表达式除了调用现有方法外什么也不做。在这些情况下,通过名称引用现有方法通常更清楚。方法引用使您能够做到这一点;它们是紧凑的、易于阅读的lambda表达式,用于已经有名称的方法。

以下是Java 8中方法引用的一些语法:

    静态方法引用(static method)语法:classname::methodname 例如:User::getAge
    对象的实例方法引用语法:instancename::methodname 例如:System.out::println
    对象的超类方法引用语法: super::methodname
    类构造器引用语法: classname::new 例如:ArrayList::new
    数组构造器引用语法: typename[]::new 例如: String[]:new

 

 

现有一个类 Something

    class Something {
     
        // constructor methods
        Something() {}
     
        Something(String something) {
        System.out.println(something);
        }
     
        // static methods
        static String startsWith(String s) {
            return String.valueOf(s.charAt(0));
        }
        
        // object methods
        String endWith(String s) {
            return String.valueOf(s.charAt(s.length()-1));
        }
        
        void endWith() {}
    }

如何用 '::' 来访问类Something中的方法呢?先定义一个接口,因为必须要用 functional interface 来接收,否则编译错误(The target type of this expression must be a functional interface)

    @FunctionalInterface
    interface IConvert<F, T> {
        T convert(F form);
    }

(@FunctionalInterface 注解要求接口有且只有一个抽象方法,JDK中有许多类用到该注解,比如 Runnable,它只有一个 Run 方法。)

观察接口 IConvert,传参为类型 F,返回类型 T。所以,我们可以这样访问类Something的方法:

访问静态方法

    // static methods
    IConvert<String, String> convert = Something::startsWith;
    String converted = convert.convert("123");

访问对象方法

     
    // object methods
    Something something = new Something();
    IConvert<String, String> converter = something::endWith;
    String converted = converter.convert("Java");

访问构造方法

     
    // constructor methods
    IConvert<String, Something> convert = Something::new;
    Something something = convert.convert("constructors");

总结:我们可以把类Something中的方法static String startsWith(String s){...}、String endWith(String s){...}、Something(String something){...}看作是接口IConvert的实现,因为它们都符合接口定义的那个“模版”,有传参类型F以及返回值类型T。比如构造方法Something(String something),它传参为String类型,返回值类型为Something。注解@FunctionalInterface保证了接口有且仅有一个抽象方法,所以JDK能准确地匹配到相应方法。
 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!