ClassCastException,将Integer强制转换为Double

53
ArrayList marks = new ArrayList();
Double sum = 0.0;
sum = ((Double)marks.get(i));

每次我尝试运行我的程序,都会收到一个ClassCastException错误,错误消息是:java.lang.Integer无法转换为java.lang.Double。

10个回答

57

我们可以将int强制转换为double,但不能对包装类IntegerDouble执行相同的操作:

 int     a = 1;
 Integer b = 1;   // inboxing, requires Java 1.5+

 double  c = (double) a;   // OK
 Double  d = (Double) b;   // No way.

这会展示对应于您运行时异常的编译时错误。


1
这是一个老问题了。Java 7允许我将Integer转换为double,而且魔法就像我预期的那样发生了:Double km = (double) (metres *1_000); - will
只是想知道为什么不能将整数转换为双精度浮点数?我有一段代码曾经可以工作,但突然停止工作,并开始对某些用例抛出相同的类型转换异常。一个失败的示例是当整数值为825842时。 - Timothy T.

37

好的,您展示的代码实际上并未包含将任何整数添加到ArrayList中 - 但如果您确实知道你有整数可以使用:

sum = (double) ((Integer) marks.get(i)).intValue();
那将把它转换为int,然后可以将其转换为double。你不能直接在装箱类之间进行强制类型转换。 请注意,如果可能使用泛型来管理ArrayList,您的代码会更清晰。

6
如果您使用Integer.doubleValue(),就不需要将int转换为doublesum = ((Integer) marks.get(i)).doubleValue();会更简洁。 - Feng Yu

12

问题中发布的代码显然不是一个完整的例子(它没有向arraylist添加任何内容,也没有在任何地方定义i)。

首先,像其他人说的那样,您需要了解原始类型和封装它们的类类型之间的区别。例如,Integer 封装了 intDouble 封装了 doubleLong 封装了 long 等等。Java 在各种情况下都会自动封箱和拆箱(以前你必须使用库调用手动封箱和拆箱,但这被认为是一种丑陋的麻烦)。

http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

你可以大多数情况下将一个原始类型强制转换成另一种原始类型(布尔型是个例外),但你不能对封装类型做同样的操作。将一个封装类型转换为另一个封装类型有点复杂。特别是如果您事先不知道盒子类型。通常,它将涉及通过一个或多个原始类型进行转换。

因此,您的问题的答案取决于您的arraylist中有什么,如果它只是类型为Integer的对象,则可以执行以下操作。

sum = ((double)(int)marks.get(i));

int转换后台将首先将marks.get的结果转换为Integer,然后将取消装箱该整数。我们然后使用另一个转换来将原始int转换为原始double。最后,当它被分配给sum变量时,结果将自动装箱回Double。(另外,在大多数情况下,让sum成为double类型而不是Double类型可能更有意义)。

如果您的ArrayList包含类型混合但它们都实现了Number接口(Integer、Short、Long、Float和Double均实现,但Character和Boolean不实现),则可以执行以下操作。

sum = ((Number)marks.get(i)).doubleValue();

如果混合在一起的还有其他类型,那么您可能需要考虑使用instanceof运算符来识别它们并采取适当的措施。


8

这里有两个需要理解的事情 -

1) 如果你将原始类型 int 转换为原始类型 double,它是可行的。例如: 它可以正常工作。

int pri=12; System.out.println((double)pri);

2) 如果您尝试将 Integer 对象转换为 Double 对象或反之亦然,则会失败。

Integer a = 1; Double b = (double) a; // WRONG. Fails with class cast excptn

解决方案 -

Soln 1) Integer i = 1; Double b = new Double(i);
soln 2) Double d = 2.0; Integer x = d.intValue();

5

请指定您的标记:

List<Double> marks = new ArrayList<Double>();

这被称为泛型。

如果ArrayList中装满了Double类型的数据,那么他就不会得到ClassCastException异常。但是这个数组必须充满整数,对吗? - Gray
2
@Gray - 一个 Integer 就足够了 ;) - Andreas Dolk

3

将整数转换为双精度浮点数

int abc=12; //setting up integer "abc"

System.out.println((double)abc); 

这段代码将把整数"abc"输出为double类型,这意味着它将显示为"12.0"。请注意,有一个小数点,表示该精度数字已被存储。

如果你想改变回来,也可以使用double。

double number=13.94;

System.out.println((int)number); 

这段代码将以整数形式在一行上输出“number”,输出结果为“13”。请注意,该值未被四舍五入,实际上是数据被省略了。

2
sum = Double.parseDouble(""+marks.get(i));

1
请考虑添加一个解释,说明您的代码片段为什么以及如何回答了 OP 的问题。 - β.εηοιτ.βε

1
Integer x=10;
Double y = x.doubleValue();

请对该代码进行一些解释。它是如何解决问题的? - Nico Haase
它将 x 从整数转换为双精度。 - Rafid
整数包装类具有doubleValue()方法,该方法返回一个double。 - vimal chaudhary

0

这意味着您的ArrayList在某些元素中具有整数。除非其中一个元素是整数,否则强制转换应该可以正常工作。

确保您的arraylist没有整数的一种方法是将其声明为Doubles数组。

    ArrayList<Double> marks = new ArrayList<Double>();

0

我认为主要问题在于你正在使用包装类进行类型转换,似乎它们是不兼容的类型。

但另一个问题是“i”是一个int类型,所以你需要将最终结果和i都进行强制类型转换。还可以尝试使用关键字“double”进行类型转换,而不是使用“Double”包装类。

你可以在这里查看:

希望这有所帮助。我发现这个讨论串很有用,但我认为这进一步澄清了其中的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接