Why does the Java 8 generic type inference pick this overload?

前端 未结 4 784
悲哀的现实
悲哀的现实 2020-11-28 07:37

Consider the following program:

public class GenericTypeInference {

    public static void main(String[] args) {
           


        
4条回答
  •  再見小時候
    2020-11-28 08:17

    In java7, expressions are interpreted from bottom up (with very few exceptions); the meaning of a sub-expression is kind of "context free". For a method invocation, the types of the arguments are resolved fist; the compiler then uses that information to resolve the meaning of the invocation, for example, to pick a winner among applicable overloaded methods.

    In java8, that philosophy does not work anymore, because we expect to use implicit lambda (like x->foo(x)) everywhere; the lambda parameter types are not specified and must be inferred from context. That means, for method invocations, sometimes the method parameter types decide the argument types.

    Obviously there's a dilemma if the method is overloaded. Therefore in some cases, it's necessary to resolve method overloading first to pick one winner, before compiling the arguments.

    That is a major shift; and some old code like yours will fall victim to incompatibility.

    A workaround is to provide a "target typing" to the argument with "casting context"

        print( (Object)new SillyGenericWrapper().get() );
    

    or like @Holger's suggestion, provide type parameter get() to avoid inference all together.


    Java method overloading is extremely complicated; the benefit of the complexity is dubious. Remember, overloading is never a necessity - if they are different methods, you can give them different names.

    提交回复
    热议问题