lambda表达式简写之方法引用,引用Integer类中的toString方法为什么编译报错

lambda表达式简写之方法引用,引用Integer类中的toString方法,Function是数据转换的函数式接口.

//使用lambda写没问题,可以实现Integer类型转换成String类型
 Function<Integer, String> function30 = t->Integer.toString(t);
//使用方法引用简化上面的代码,却编译报错
 Function<Integer, String> function3 = Integer::toString;

我的分析一: toString方法的参数是int类型,于是我自定义了一个f方法,如下,结果是正常引用该方法,不会报错.说明不是int类型的问题,可以自动拆箱

  Function<Integer, String> function2 = _Lambda::f;

  public static String f(int i){
        return Integer.toString(i);
    }

我的分析二: toString方法有3个重载方法, 于是我自定义了2个重载方法去尝试,发现也没有问题不会报错

         //Integer中的3个重载方法
         public static String toString(int i) ;
         public static String toString(int i, int radix);
         public String toString()
         

//引用f2,不会报错,可以实现类型转换,说明不是重载的问题
Function<Integer, String> function23 = _Lambda::f2;
 public static String f2(Integer i){
        return Integer.toString(i);
    }
  public static String f2(){
        return "123";
    }

请问,Function<Integer, String> function3 = Integer::toString;问题出在了?为什么编译报错?求解答!

阅读 4.4k
2 个回答

方法引用表达式Integer::toString可以表示引用IntegertoString静态方法

Function<Integer, String> f = t -> Integer.toString(t)

也可以表示引用任意Integer实例toString成员方法

Function<Integer, String> f = t -> t.toString()

编译器无法判断应该使用哪个解释

你自己定义的类中最后一个f2由于是静态的,不会有这种冲突,所以编译可以通过
你自己定义的类中没有这种冲突,所以编译可以通过

以下是两个冲突的示例

public class Demo {

    public static void main(String[] args) {
        Function<Demo, String> function2 = Demo::f2;
        BiFunction<Demo, Integer, String> function3 = Demo::f3;
    }
    public static String f2(Demo i) {
        return "456";
    }

    public  String f2() {
        return "123";
    }
    
    public static String f3(Demo demo, int i) {
        return "456";
    }

    public  String f3(int i) {
        return "123";
    }
}

编译报错信息如下

Error:(9, 44) java: 不兼容的类型: 方法引用无效
    对f2的引用不明确
      Demo 中的方法 f2(Demo) 和 Demo 中的方法 f2() 都匹配
Error:(10, 55) java: 不兼容的类型: 方法引用无效
    对f3的引用不明确
      Demo 中的方法 f3(Demo,int) 和 Demo 中的方法 f3(int) 都匹配

方法引用的4种类型:

Kind Example
Reference to a static method ContainingClass::staticMethodName
Reference to an instance method of a particular object containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type ContainingType::methodName
Reference to a constructor ClassName::new

注意第一种和第三种在书写形式上是一样的

表格摘自methodreferences

Function<Integer, String>表示接受参数Integer且返回String的方法。

所以是下面两个重载的问题:

public static String toString(int i);
public String toString();

而你只实验了两个static方法,一个有参数Integer,一个没有,编译器是能分别出来的。如果你把f2定义中的static也会报错的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题