gpt4 book ai didi

java - 为什么 Java 中的桥接方法不阻止这种情况并抛出异常?

转载 作者:行者123 更新时间:2023-11-30 06:41:45 25 4
gpt4 key购买 nike

为什么下面的泛型代码在运行时没有抛出异常?

public static void main(String[] args) {
((List)new ListString()).add(3);
}


static class ListString extends ArrayList<String>{

}

我知道这不是应该如何使用泛型,但我认为 the bridge methods将通过添加以下抛出 ClassCastException.

的方法来解决该问题
public boolean add(Object o){
return add((E)o);
}

注意:如果我按照以下修改 ListString 类,这确实会抛出 ClassCastException:

static class ListString extends ArrayList<String>{
@Override
public boolean add(String o){
return super.add(o);
}
}

最佳答案

除非您实际编写该方法,否则不会创建桥接(合成方法),就像您在后续测试中所做的那样,您确实放置了 public boolean add(String o){return super.add(o);}。在代码中。

当您调用 .get(someInt) 时在 StringList 类型的表达式上,编译器可以看到你的 StringList类型,即使它是 ArrayList<String> 的子类型, 没有任何带有签名的方法 String get(int)在里面。因此,它生成对 Object get() 的调用字节码中的方法,另外(如果需要)一个强制转换,在 Java 方面,它的行为就好像 StringList 上的 get 方法一样。返回字符串。即使在字节码级别,它也不是。

如果你然后制作一个 String get(int)方法出现,例如通过子类化 StringList ,或者通过编辑源代码并只重新编译该文件,然后才生成桥接方法。因为 java 是动态调度,所以总是使用那个桥接器。桥转换和调用(或调用和转换,取决于桥是否涵盖返回类型恶作剧或参数恶作剧)。

您可以使用 javap -v 验证所有这些:我强烈建议所有觉得这很有趣并且想确切地知道它是如何工作的人探索这两者之间输出差异的乐趣:

import java.util.*;

public class Test extends ArrayList<String> {
public static void main(String[] args) {
List raw = new Test();
raw.add(3);
}
}

还有这个:

import java.util.*;

public class Test extends ArrayList<String> {
public static void main(String[] args) {
List raw = new Test();
raw.add(3);
}
public boolean add(String o) {
return super.add(o);
}
}

关于java - 为什么 Java 中的桥接方法不阻止这种情况并抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54709580/

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