I figured Java 10's local variable type inference (var name = ...;) would be the answer to this conundrum. Instead of the destination variable type providing the type for the method reference, the right-hand-side would need to fully specify the type, necessitating the type parameter (::<T>) on the method reference.
First thought out the gate ...
var arraySorter = Arrays::<Double>sort;
... but method references, by themselves, do not define a type. They need to be translated to a functional object by the compiler, and the compiler won't search for known functional interfaces looking for the appropriate type, even if there was exactly one.
Next thought was to use a method reference as an argument to a method which returns a type based on the method's argument.
class Spy { static <T> Function<T,T> f2(Function<T,T> f) { return f.andThen(f); } static <T> T identity(T t) { return t; } }
Using this, we can create our local variable passing a method reference to our method:
Function<Double,Double> double_identity = f2(Spy::<Double>identity);
As expected, we can remove the ::<Double>
Function<Double,Double> double_identity = f2(Spy::identity);
Unexpectedly, local variable type inference is fine with it.
var double_identity = f2(Spy::identity); // Infers <Object>! Object obj = null; double_identity.apply(obj);
But the real surprise comes when use the method reference type to override it.
var double_identity = f2(Spy::<Double>identity); // Error: Double != Object
After a bit of fighting, I figured out why. We have to apply the type to the f2 method itself:
var double_identity = Spy.<Double>f2(Spy::identity); // Works.
In retrospect, this makes some sense. The type of the variable generally provides context for the outer function. Assigning the result to a Function<Double,Double> variable lets the compiler infer the type of f2(...), which then passes that type to the arguments. With var name = ..., without an explicit type, the only type is has available is Object, so the compiler infers Spy.<Object>f2(...), and then determines the argument type must be a Function<Object,Object>.
Unfortunately, it doesn't seem to parse from the inside out, so that Spy::<Double>identity doesn't cause the function to be inferred as Spy.<Double>f2(...) and the variable as Function<Double,Double>. Maybe Java 11? Maybe it would break too much, and can't work.
It does, however, put an end to my attempts to abuse var name = ...; to solve the OP's conundrum.
Many thanks to @Eugene for critiquing my previous attempts prior to Java 10's release.
FooBaris derived fromFoo: in Java7:List<Foo> foo = Arrays.asList(new FooBar());won’t compile, but it will compile in Java8. Java7 needs the type parameter:List<Foo> foo = Arrays.<Foo>asList(new FooBar());.::<T>notation.