我认为Java 10的局部变量类型推断(var name = …;)将是这个难题的答案.右侧需要完全指定类型,而不是提供方法引用类型的目标变量类型,而需要在方法引用上使用类型参数(::< T>).
首先想到了大门……
var arraySorter = Arrays::sort;
…但方法引用本身并不定义类型.它们需要由编译器转换为功能对象,并且编译器不会搜索寻找适当类型的已知功能接口,即使只有一个.
接下来的想法是使用方法引用作为方法的参数,该方法基于方法的参数返回类型.
class Spy {
static Function f2(Function f) {
return f.andThen(f);
}
static T identity(T t) {
return t;
}
}
使用这个,我们可以创建我们的局部变量,将方法引用传递给我们的方法:
Function double_identity = f2(Spy::identity);
正如所料,我们可以删除::< Double>
Function double_identity = f2(Spy::identity);
出乎意料的是,局部变量类型推断很好.
var double_identity = f2(Spy::identity); // Infers !
Object obj = null;
double_identity.apply(obj);
但是当使用方法引用类型来覆盖它时,真正的惊喜就出现了.
var double_identity = f2(Spy::identity); // Error: Double != Object
经过一番战斗,我弄明白了为什么.我们必须将类型应用于f2方法本身:
var double_identity = Spy.f2(Spy::identity); // Works.
回想起来,这是有道理的.变量的类型通常为外部函数提供上下文.将结果分配给函数< Double,Double>变量让编译器推断f2(…)的类型,然后将该类型传递给参数.使用var name = …,没有显式类型,唯一可用的类型是Object,因此编译器会推断Spy.< Object> f2(…),然后确定参数类型必须是Function标识不会导致函数被推断为Spy.< Double> f2(…)并且变量为功能
但是,它确实结束了我滥用var name = …的企图;解决OP的难题.
非常感谢@Eugene批评我之前在Java 10发布之前的尝试.