Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 返回类型中的推断通配符泛型_Java_Generics_Bounded Wildcard - Fatal编程技术网

Java 返回类型中的推断通配符泛型

Java 返回类型中的推断通配符泛型,java,generics,bounded-wildcard,Java,Generics,Bounded Wildcard,Java通常可以根据参数推断泛型(甚至可以根据返回类型,与C#相反) 举个例子:我有一个泛型类Pair,它只存储一对值,可以用以下方式使用: Pair<String, String> pair = Pair.of("Hello", "World"); 非常好。但是,这不再适用于以下需要通配符的用例: Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello"); 有人

Java通常可以根据参数推断泛型(甚至可以根据返回类型,与C#相反)

举个例子:我有一个泛型类
Pair
,它只存储一对值,可以用以下方式使用:

Pair<String, String> pair = Pair.of("Hello", "World");
非常好。但是,这不再适用于以下需要通配符的用例:

Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello");
有人能解释一下这种行为吗?这是设计的吗?需要吗?我是做错了什么,还是无意中发现了编译器中的设计缺陷/bug


胡乱猜测:“capture#1-of?”似乎在某种程度上暗示,通配符是由编译器动态填充的,使类型a
,从而导致转换失败(从
Pair来看,构造函数工作的原因是您显式指定了类型参数。如果您这样做,静态方法也会工作:

Pair<Class<?>, String> pair = Pair.<Class<?>, String>of(List.class, "hello");
Pair,String>of(List.class,“hello”);
当然,首先使用静态方法的全部原因可能只是为了得到类型推断(它根本不适用于构造函数)

这里的问题(正如您所建议的)是编译器正在执行。我相信这是由于:

  • 所选方法的结果类型确定如下:
    • 如果调用的方法声明的返回类型为void, 那么结果是无效的
    • 否则,如果未选中的转换对于 方法适用于 结果类型是对数据的擦除(§4.6) 方法声明的返回类型
    • 否则,如果调用的方法是泛型的,则对于1in,让 Fi是的形式类型参数 方法,让Ai成为实际类型 为该方法推断的参数 调用,并将R声明为 正在执行的方法的返回类型 调用。获取结果类型 通过应用捕获转换 (§5.1.10)至R[F1:=A1,…,Fn:= 安]
    • 否则,通过应用捕获来获得结果类型 将(§5.1.10)转换为给定类型 在方法声明中
如果您真的想要推断,一种可能的解决方法是执行以下操作:

public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
    return new Pair<T1, T2>(first, second);
}
Pair<? extends Class<?>, String> pair = Pair.of(List.class, "hello");
Pair,String>Pair=Pair.of(List.class,“hello”);

变量
对将有一个更宽的类型,这确实意味着在变量的类型名称中键入更多的类型,但至少您不需要再强制转换方法调用。

转换器似乎看到了“of”的签名当它返回一个PairHmmm时,很有趣。感谢您将我链接到这里。它现在在java8中工作。对于inferene,目标类型也会被查询。非常感谢。我仍在考虑解决方法是否不会使核心更加混乱。目前,我将保持原样。
Pair<Class<?>, String> pair = Pair.<Class<?>, String>of(List.class, "hello");
Pair<? extends Class<?>, String> pair = Pair.of(List.class, "hello");