我找到了一种通过泛型类型向整数数组添加浮点的方法.我很好奇为什么Java不能在运行时错误中捕捉到这一点?我试着在文档中查找有关这方面的任何信息,但我没有任何运气.

例如,假设我有两个ArrayList,一个包含整数,另一个包含浮点,如下所示:

ArrayList<Integer> listInt = new ArrayList<>();
ArrayList<Float> listFlt = new ArrayList<>();
  
listInt.add(6);
listInt.add(71);
  
listFlt.add(4.92f);
listFlt.add(20.5f);

使用泛型,我可以通过以下方法将浮动从listFlt复制到listInt:

public static <T extends Number, S extends Number> void copy(ArrayList<T> src, ArrayList<S> dest) {
   for (int i = 0; i < src.size(); i++) {
       Object x = src.get(i);
       dest.set(i, (S)x);
   }
}

通过以下方式调用:

ClassName.<Float, Integer>copy(listFlt, listInt);

现在,当我打印listInt时,它显示:

4.92
20.5

当涉及泛型时,如何将对象强制转换为整数?listInt如何存储浮动?谢谢

推荐答案

通过使用泛型,我可以通过如下方法将浮点从listFlt复制到listInt

请注意,在此方法中,您将强制转换为类型参数S:

dest.set(i, (S)x);

编译时,这将导致未经判断的强制转换警告(不应忽略!).

这是允许的,但由于类型擦除,JVM将无法在编译时判断是否允许强制转换.

这是heap pollution的一个例子:由于Java语言和类型擦除的规则,您会遇到这样的情况:您可以将类型错误的对象添加到ArrayList中(在本例中:您将Float个对象添加到一个应该包含Integer个对象的列表中).

当您只打印列表时,没有问题,因为在这种情况下,Java只需要对列表的元素调用toString(),并且该方法适用于所有对象.

但当你试图从列表中得到Integer分时,你会得到ClassCastException分:

ClassName.<Float, Integer>copy(listFlt, listInt);

Integer i = listInt.get(0); // ClassCastException: Float cannot be cast to Integer

这是Java规则组合的不幸结果,部分原因是向后兼容性,以及Java处理泛型(类型擦除)的方式.

Point to remember:不要忽略"未经判断的强制转换"警告;它们暗示代码中可能存在堆污染.

Java相关问答推荐

我正在try 对用户输入的整元进行气泡排序(Java)

在Keycloak测试容器中的测试之间清理数据库

在Java中将Charsequence数组更改为String数组或List String<>

现场观看Android Studio中的变化

Exe4j创建的应用程序无法再固定在任务栏Windows 11上

所有 case 一起输入时输出错误,而单独放置时输出正确

如何创建一个2d自上而下的移动系统,其中移动,同时持有两个关键是可能的处理?

呈现文本和四舍五入矩形时出现的JavaFX窗格白色瑕疵

在Java中,在单个逻辑行中连接列表和单个元素的正确方法是什么?

如何正确创建序列图?

Mac上的全屏截图在使用JavaFX时不能正常工作吗?

生成桥方法以解决具有相同擦除的冲突方法

Spring安全令牌刷新和JWT签名与本地计算的签名不匹配

Java页面筛选器问题

如何在Spring Boot中创建可以将值传递给配置的&Enable&Quot;注释?

如何在@CsvSource中传递空格作为值

一对多关系和ID生成

如果执行@BeForeEach#repository.save(),则测试中的UnitTest最终UUID会发生更改

如何通过Java java.lang.Foreign API访问本机字节数组

Java方法参数:括号中的类型声明?