java - 为什么泛型的这种使用不会引发运行时或编译时异常?
问题描述
我在一个类中有一个方法,该方法具有通过使用泛型指定的返回类型。
public class SomeMain {
public static void main(String[] args) {
Foo<Integer> foo = new Foo<Integer>();
System.out.println(foo.getFoo()); // Works, prints out "Foo"
}
public static class Foo<E> {
public E getFoo() {
return (E) "Foo";
}
}
}
对于通用返回类型,我假设上面示例中的返回值将计算为:
return (Integer) "Foo"; // Inconvertible types !!!
而是String
返回并正确打印 a。
如果我将调用更改为:
String fooString = foo.getFoo(); // Compile error, incompatible types found
System.out.println(fooString);
我缺少什么来帮助我理解这里发生了什么以及为什么原始版本没有导致编译错误。
解决方案
这是因为重载决议解决了您对 的println
调用println(Object)
,因为没有println(Integer)
.
请记住,Java 的泛型在运行时会被删除。并且演员喜欢(E) "Foo"
被删除,并被移动到呼叫站点。有时这不是必需的,因此仅在需要时才将事物转换为正确的类型。
换句话说,内部不执行任何类型转换getFoo
。语言规范支持这一点:
第 5.5.2 节 检查的强制转换和未检查的强制转换
演员表是完全未经检查的演员表。
不会对此类强制转换执行任何运行时操作。
擦除后,getFoo
返回Object
。这被传递到println(Object)
,这非常好。
如果我调用这个方法并通过foo.getFoo
,我会得到一个错误:
static void f(Integer i) {
System.out.println(i);
}
// ...
f(foo.getFoo()); // ClassCastException
因为这一次需要铸造。
推荐阅读
- java - 如何在Java中将数据从一个json对象传递到另一个?
- javascript - 文本框根据 php 中的下拉选择动态填充 db 值
- javascript - 在 JavaScript 中为 A* 生成启发式查找表
- java - Android:如何在选项卡选择上禁用默认弹出 TabLayout 动画
- javascript - 非常基本的例子不起作用
- actions-on-google - 在对完整 URL 发出的任何请求中均未收到授权标头
- sql-server - 十进制除法时如何获得商和余数?
- javascript - DOM 中的 hasAttribute 无法正常工作
- spring-mvc - 如何正确设置休眠验证器 6.0.10.Final
- c# - 如何在运行时更改 asp.net core 中的启动数据?