Java 8方法引用类型推断

时间:2014-08-13 16:45:55

标签: java generics java-8

我对Java 8的类型推断感到困惑。以下代码:

private static <T> Function<Iterable<? extends T>, Iterator<? extends T>>
    toIterator() {
  return Iterable<? extends T>::iterator;
}

打破编译错误

error: incompatible types: invalid method reference
    return Iterable<? extends T>::iterator;
           ^
    method iterator in interface Iterable<T#2> cannot be applied to given types
      required: no arguments
      found: Iterable<? extends T#1>
      reason: actual and formal argument lists differ in length
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in method <T#1>toIterator()
    T#2 extends Object declared in interface Iterable

而删除显式泛型

private static <T> Function<Iterable<? extends T>, Iterator<? extends T>>
    toIterator() {
  return Iterable::iterator;
}

起作用,老派匿名内部班级也是如此

private static <T> Function<Iterable<? extends T>, Iterator<? extends T>>
    toIterator() {
  return new Function<Iterable<? extends T>, Iterator<? extends T>>() {
    @Override
    public Iterator<? extends T> apply(Iterable<? extends T> iterable) {
      return iterable.iterator();
    }
  };
}

有人可以建议可能会发生什么吗?

1 个答案:

答案 0 :(得分:5)

使用<? extends T>是错误的,因为对于具有显式类型参数的通用调用,您必须指定完整类型,而不是通配符类型。

如果您只是使用

private static <T> Function<Iterable<? extends T>, Iterator<? extends T>>
    toIterator() {
  return Iterable::iterator;
}

Java会为你推断出类型。


解决方案是:

private static <T> Function<Iterable<T>, Iterator<? extends T>> toIterator() {
  return Iterable<T>::iterator;
}

虽然不清楚将Function的返回类型扩展到? extends T的优势是什么。对于实际用途,

private static <T> Function<Iterable<T>, Iterator<T>> toIterator() {
  return Iterable<T>::iterator;
}

将是最有用的方法签名。为此,推断Iterable::iterator仍然有效。


关于编译器错误消息,这似乎只是错误报告中的错误,当对非static方法的方法引用具有类型不匹配时,该错误始终适用。它甚至可以通过简单的声明再现:

Consumer<Object> c=String::getClass;

产生错误消息:

error: incompatible types: invalid method reference
Consumer<Object> c=String::getClass;
                   ^
method getClass in class Object cannot be applied to given types
  required: no arguments
  found: Object
  reason: actual and formal argument lists differ in length

请注意,对static方法的引用会收到正确的错误消息:

Consumer<Object> c=Class::forName;

产生

error: incompatible types: invalid method reference
Consumer<Object> c=Class::forName;
                   ^
incompatible types: Object cannot be converted to String