Inferred wildcard generics in return type

試著忘記壹切 提交于 2019-11-28 09:06:06
Laurence Gonsalves

The reason the constructor works is that you're explicitly specifying the type parameters. The static method also will work if you do that:

Pair<Class<?>, String> pair = Pair.<Class<?>, String>of(List.class, "hello");

Of course, the whole reason you have a static method in the first place is probably just to get the type inference (which doesn't work with constructors at all).

The problem here (as you suggested) is that the compiler is performing capture conversion. I believe this is as a result of [§15.12.2.6 of the JLS]:

  • The result type of the chosen method is determined as follows:
    • If the method being invoked is declared with a return type of void, then the result is void.
    • Otherwise, if unchecked conversion was necessary for the method to be applicable then the result type is the erasure (§4.6) of the method's declared return type.
    • Otherwise, if the method being invoked is generic, then for 1in, let Fi be the formal type parameters of the method, let Ai be the actual type arguments inferred for the method invocation, and let R be the declared return type of the method being invoked. The result type is obtained by applying capture conversion (§5.1.10) to R[F1 := A1, ..., Fn := An].
    • Otherwise, the result type is obtained by applying capture conversion (§5.1.10) to the type given in the method declaration.

If you really want the inference, one possible workaround is to do something like this:

Pair<? extends Class<?>, String> pair = Pair.of(List.class, "hello");

The variable pair will have a wider type, and it does mean a bit more typing in the variable's type name, but at least you don't need to cast in the method call anymore.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!