【问题标题】:Java Generics and Lambda functions [duplicate]Java泛型和Lambda函数[重复]
【发布时间】:2015-01-30 07:26:01
【问题描述】:

我有一个带有重载方法的类。我希望它采用 lambda 函数或可比较的数字(因为我必须检查方法的值)

public class Factory {
    public static LambdaHandler create(Runnable fn){
         return new LambdaHandler(fn);
    }

    public static <T extends Number & Comparable<T>>  NumberHandler create(T number){
        return new NumberHandler<>(number);
    }
}

但是,当我尝试在另一个类中调用这些方法时,我得到了一个模棱两可的匹配错误。

@Test
public void testSomething() throws Exception {
    create(() -> { }).handle();
}

任何想法如何解决这个问题?

干杯,

【问题讨论】:

  • 写下您遇到的错误。

标签: java generics lambda java-8


【解决方案1】:

这是模棱两可的,因为可能有一个类型 T 可以被 lambda 表达式匹配,所以编译器不知道当你传递一个 lambda 时要调用两个 create() 方法中的哪一个表达。

你可以投到Runnable:

create((Runnable) () -> { }).handle();

或者把它放在一个变量中:

Runnable fn = () -> {};
create(fn).handle();

或者给方法起不同的名字,这样它们就不会被重载:

public class Factory {
    public static LambdaHandler createFn(Runnable fn){
         return new LambdaHandler(fn);
    }

    public static <T extends Number & Comparable<T>>  NumberHandler createNum(T number){
        return new NumberHandler<>(number);
    }
}

【讨论】:

  • 但是我的第二个创建类型是 T extends Number & Comparable 这不限制它为可比较的数字
  • Runnable 是一个接口。所以你可以创建class MyRunnableNumber extends Number implements Runnable,Comparable
  • @Terry Storm:这完全是题外话。问题是为什么用 lambda 表达式 调用方法是模棱两可的,而 lambda 表达式永远不能扩展 Number
  • @Jesper:我不明白这一点。如果您使用这样的MyRunnableNumber 实例进行方法调用,则该调用将是模棱两可的。但这并不能解释为什么传递 lambda 表达式是模棱两可的。您可以创建一个同时实现RunnableCallable 的类,那么ExecutorService.submit 将与该类不明确。尽管如此,这并不意味着对 submit 的每次调用都是模棱两可的,甚至将 lambda 表达式传递给 submit 也不是(使用最新的 jdk)。
  • 调用哪个重载方法的决定是由编译器在编译时做出的,而在运行时可能存在的任何类都是完全不相关的。如果您想了解真正的推理而不是猜测,请阅读Stuart Marks’ answer,他解释说,将方法重载决议和类型推断分开是语言设计者的深思​​熟虑的决定,以简化规范和实现,但代价是在某些方面失败不是真正模棱两可的情况。引用他的话:“这是一个颇具争议的决定”
猜你喜欢
  • 2018-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
相关资源
最近更新 更多