下面的代码可正常编译,但在运行时引发异常。这是预期的行为,为什么?

代码:

public static void main(String[] args) {
  A<Integer> a = new A<> ();
  System.out.println(a.min()); //prints null as expected
  System.out.println(a.max()); //throws exception
}

static class A<T extends Number & Comparable<? super T>> {
  Stream<T> s = Stream.empty();
  public T min() { return s.min((t1, t2) -> t1.compareTo(t2)).orElse(null); }
  public T max() { return s.max(T::compareTo).orElse(null); }
}

输出:
null
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
    at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
    at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
    at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
    at abc$A.max(abc.java:19)
    at abc.main(abc.java:8)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Number; not a subtype of implementation type interface java.lang.Comparable
    at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
    at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
    at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
    ... 4 more

最佳答案

即使使用lambda而不是方法引用,您的代码也无法正常工作,因为流已耗尽

 System.out.println(a.min());
 System.out.println(a.max()); // exhausted

流是一回事。但是,让我们分开。当您使用方法引用版本时,它将捕获Number作为类型参数,而不是Comparable,其中Number没有compareTo 也许是,因为Number在这里更具体。
如果您只使用Comparable,它将可以正常工作
  static class A<T extends Comparable<? super T>> {
    Stream<T> s = Stream.empty();
    public T min() { return s.min((t1, t2) -> t1.compareTo(t2)).orElse(null); }
    public T max() {
        T t = s.max(T::compareTo).orElse(null);
        return t; }
 }

System.out.println(a.max()); //null

IMO(请谨慎):我相信这是一个错误。

我真正相信的是:绝对是一个错误。

编辑:事实证明,这实际上是一个错误,已得到Brian Goetz的修复。 https://bugs.openjdk.java.net/browse/JDK-8058112。根据错误数据库,此问题已在8u40中修复

关于java - 混合方法引用和泛型时的LambdaConversionException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33507404/

10-10 14:10