gpt4 book ai didi

java - 参数的 Java 编译时分派(dispatch)是否损坏?

转载 作者:行者123 更新时间:2023-11-30 09:05:13 25 4
gpt4 key购买 nike

我已经知道 Java 根据编译时类型分派(dispatch)方法。但是我有一个案例,我希望它能起作用,但它没有。

考虑这个简单的例子:

class Foo{ 
void bar(Object... objects) { //do something }

void bar(Map<String, Object> map) { //do something else }
}

和调用代码:

Foo foo = new Foo();
HashMap<String, T> map = createSomeHashMap(); //wil generate HashMap
foo.bar(map);

为什么 Java 认为调用 bar(Object... objects) 最合适? ?因为我在编译时有一个 map ,所以一切都应该有效!为什么我必须像 foo.bar((Map<String, Object>)map); 这样明确地向下转换它??

最佳答案

我在下面尝试了这个程序并得到了一个错误 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...它通常会解析为。

关于java - 参数的 Java 编译时分派(dispatch)是否损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24917787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com