好的,如果我有这个代码
double a=1.5;
int b=(int)a;
System.out.println(b);
一切正常,但
Object a=1.5;
int b=(int)a;
System.out.println(b);
运行后出现以下错误(Eclipse没有给出任何错误)
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
但是,当我这样做时
Object a=1.5;
double b=(double)a;
int c=(int)b;
System.out.println(c);
或
Object a=1.5;
int b=(int)(double)a;
System.out.println(b);
再没有错。
为什么必须先将它投射到double
?
答案 0 :(得分:3)
当您声明对象Object a = 1.5
时,您可以通过检查System.out.println(a.getClass())
该对象实际上是否转换为Double
实例来判断。由于取消装箱约定,这可以再次转换为double
。之后,double
值可以转换为int
。
但是,从Double实例转换为int
没有取消装箱约定,因此如果您尝试执行此操作,运行时将发出ClassCastException
。它不能直接从Double
转到Integer
。
答案 1 :(得分:3)
当您从Object
进行投射时,您从包装类型中重新unboxing ...并且您只能取消装箱到原始类型。它实际上是对相关包装器类型的强制转换,然后调用相应的xxxValue
方法。所以这个:
Object x = ...;
double d = (double) x;
相当于:
Object x = ...;
double d = ((Double) x).doubleValue();
如果Double
不是对x
的引用,那么对Double
的强制转换显然会失败。
所以你有问题的代码相当于:
Object a = Double.valueOf(1.5); // Auto-boxing in the original code
int b = ((Integer) a).intValue(); // Unboxing in the original code
System.out.println(b);
希望现在很明显为什么会失败 - 因为第一行会创建一个Double
,然后您尝试投放到Integer
。
答案 2 :(得分:1)
我不确定为什么你的代码会起作用。您不应该将对象强制转换为' double'因为它们是不兼容的类型。另外,将int类型转换为double是不兼容的类型。你的第一段代码:
double a=1.5;
int b=(int)a;
System.out.println(b);
将打印" 1"。你将失去小数。如果您只想在小数点之前打印数字,那么您可以在打印时格式化双精度,并且您不需要强制转换为int类型。
但是其他人不能工作的原因是因为你试图强制转换为不兼容的类型。你说最后两个代码块
是很奇怪的Object a=1.5;
double b=(double)a;
int c=(int)b;
System.out.println(c);
Object a=1.5;
int b=(int)(double)a;
System.out.println(b);
由于类型不兼容,这些不应该起作用。