java - List[Int] 和 List[Integer] 类型擦除的区别
问题描述
为什么List[scala.Int]
type erase to List[Object]
while Integer
inList[java.lang.Integer]
似乎被保留了?例如,javap
对于
object Foo {
def fooInt: List[scala.Int] = ???
def fooInteger: List[java.lang.Integer] = ???
}
输出
public scala.collection.immutable.List<java.lang.Object> fooInt();
public scala.collection.immutable.List<java.lang.Integer> fooInteger();
我们看到的地方Integer
在第二种情况下被保留了。文档状态
将泛型类型中的所有类型参数替换为其边界,或者
Object
如果类型参数是无界的。
这可能是由于“界限”条款吗?如果是这样,这个界限在哪里指定?
解决方案
我不是scala 开发人员,对此持保留态度。擦除是一样的:
public static scala.collection.immutable.List<java.lang.Object> fooInt();
descriptor: ()Lscala/collection/immutable/List;
public static scala.collection.immutable.List<java.lang.Integer> fooInt();
descriptor: ()Lscala/collection/immutable/List;
看descriptor
参数;这就是调用站点在字节码级别上引用的内容。
当您简单地这样做时javap
,它会通过查看Signature
参数(进一步阅读)来“作弊”,以便向您展示这个无害的小谎言。
现在想想。让我们采用这个方法并将其放在 class 中A
:
static List<Integer> test() {
return null; // or whatever that is not the point
}
我们编译它,将.class
文件分享给其他人。其他人以这种形式使用它:(实际上没有源代码A
)。
public void testMe() {
Integer x = A.test().get(0);
}
如果您查看字节码,您将看到:
5: invokeinterface #3, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
10: checkcast #4 // class java/lang/Integer
必须立即提出一个问题:如果泛型被删除,它如何知道Integer
(通过那个)?checkcast
答案是编译Signature
时生成的可选选项,或者在您的情况下:A
()Lscala/collection/immutable/List<Ljava/lang/Object;>; //fooInt
()Lscala/collection/immutable/List<Ljava/lang/Integer;>; // fooInteger
Signature
编译器使用此信息通过运行时检查在调用点强制执行类型安全;如果该字段不存在 - 那将是不可能的。
现在为什么Signature
ofscalac
生成(因此调用者的Object
零类型安全)是重复地址的东西。我已尝试阅读该问题,但这并不容易阅读-我只会选择“我相信你”。
更多解释:Signature
出现在java-5
添加泛型时。在此之前,所有由 引用的调用站点descriptor
,将其更改为Signature
将意味着现有代码将中断;因此从未完成。因此Signature
成为可选的并以不同的方式使用 - for checkcast
。至少这是我强烈倾向于假设的:)
推荐阅读
- php - 分页时将锚点添加到第 2 页的第 1 页上一个链接
- node.js - 更新嵌套对象数组中的名称
- forms - UI5:验证整个表单的空值/空白值的必填和可见字段
- node.js - Nodejs 云函数 - 并非所有代码路径都返回值
- list - 使用列表在购物车中创建项目列表(Flutter Web)
- python - A 返回地图中树的数量
- sql - 执行 CREATE TABLE SQL 命令时未创建 Wordpress 表
- ruby-on-rails - Mysql2::Error:Rails 5升级后字段'key'没有默认值
- java - 有没有办法防止自动异常处理?
- vba - 使用循环为所有记录填充报表上的未绑定文本框