我在下面尝试了这个程序并得到了一个错误Type mismatch: T cannot be converted to Object
:
public class DispatchTest
{
private void bar( HashMap<String, Object> map )
{
}
public static void main( String[] args )
{
test();
}
private static <T> void test()
{
DispatchTest dt = new DispatchTest();
HashMap<String,T> map = new HashMap<>();
dt.bar( map );
}
}
所以我想是泛型把你搞砸了。将参数的类型从 更改Object
为?
,这对我有用。
private void bar( HashMap<String, ?> map )
{
}
编辑:只是为了详细说明这一点,我将代码恢复为原始代码,并添加了一个类似于您的示例的方法bar(Object...)
。下面是生成的 Java 字节码:
private static <T extends java/lang/Object> void test();
Code:
0: new #3 // class quicktest/DispatchTest
3: dup
4: invokespecial #4 // Method "<init>":()V
7: astore_0
8: new #5 // class java/util/HashMap
11: dup
12: invokespecial #6 // Method java/util/HashMap."<init>":()V
15: astore_1
16: aload_0
17: iconst_1
18: anewarray #7 // class java/lang/Object
21: dup
22: iconst_0
23: aload_1
24: aastore
25: invokevirtual #8 // Method bar:([Ljava/lang/Object;)V
28: return
您可以看到,在这种情况下,已经做出了Map
参数不合适的决定,并且第 25 行的 invokevirtual 字节码Object...
需要调用的版本。这是在编译时完成的,而不是运行时。
如果我将代码改回我的建议(使用Map<String,?>
),则 invokevirual 字节码会要求提供 Map 参数。您的版本也可以工作,因为强制转换强制编译器为 Map 发出 invokevirtual,而不是 Object ......它通常会解析为。