在Java中转换变量

时间:2011-03-13 12:41:51

标签: java casting

我想知道是否有人能告诉我铸造是如何工作的?我理解何时我应该这样做,但不是真的如何运作。在原始数据类型上我部分理解但是当涉及到构建对象时,我不明白它是如何工作的。

如何突然将类型为Object的对象强制转换为MyType(仅作为示例),然后获取所有方法?

5 个答案:

答案 0 :(得分:168)

使用Java进行投射并不神奇,而是告诉编译器类型A的对象实际上是更具体的类型B,因此可以访问B上的所有其他方法。你在执行转换时没有执行任何魔法或转换,你实际上是在告诉编译器“相信我,我知道我在做什么,我可以保证你在这一行的这个对象实际上是一个< Insert这里的演员类型>。“例如:

Object o = "str";
String str = (String)o;

以上是好的,不是魔法,一切都很好。存储在o中的对象实际上是一个字符串,因此我们可以毫无问题地转换为字符串。

有两种方法可能出错。首先,如果你在完全不同的继承层次结构中的两种类型之间进行转换,那么编译器就会知道你是愚蠢的并阻止你:

String o = "str";
Integer str = (Integer)o; //Compilation fails here

其次,如果它们在同一个层次结构中但仍然是无效的强制转换,那么将在运行时抛出ClassCastException

Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here

这实际上意味着您违反了编译器的信任。你告诉它你可以保证对象属于特定类型,但事实并非如此。

为什么需要施法?好吧,从一开始就只需要从更通用的类型到更具体的类型。例如,Integer继承自Number,因此如果您想将Integer存储为Number,那就没问题(因为所有整数都是数字。)但是,如果你想要反过来你需要一个演员 - 不是所有的数字都是整数(以及整数我们有DoubleFloatByteLong等。 )即使你的项目中只有一个子类或JDK,有人可以很容易地创建另一个并分发它,所以即使你认为它是一个明显的选择,你也无法保证!

关于使用铸造,你仍然会在某些库中看到它的需要。在Java-5之前,它在集合和各种其他类中被大量使用,因为所有集合都在处理添加对象,然后将结果转换回集合。然而,随着仿制药的出现,大部分用于铸造的东西已经消失 - 它已经被泛型替代,它提供了更安全的替代方案,没有ClassCastExceptions的可能性(事实上如果你干净地使用泛型并且它没有警告编译,你可以保证你永远不会得到ClassCastException。)

答案 1 :(得分:7)

实际上,施法并不总是有效。如果该对象不是instanceof您正在将其投射到的类,则会在运行时获得ClassCastException

答案 2 :(得分:5)

假设您想要将String转换为File(是的,它没有任何意义),您不能直接转换它,因为File类不是孩子而不是String类的父级(以及编译器抱怨)。

但是您可以将String转换为Object,因为StringObjectObject是父级)。然后,您可以将此对象转换为File,因为文件是Object

因此,在编译时,从打字的角度来看,所有操作都是“合法的”,但这并不意味着它将在运行时运行!

File f = (File)(Object) "Stupid cast";

即使没有意义,编译器也允许这样做,但是在运行时它会因此异常而崩溃:

Exception in thread "main" java.lang.ClassCastException:
    java.lang.String cannot be cast to java.io.File

答案 3 :(得分:2)

投射引用只有在instanceof类型的情况下才有效。您无法投射随机参考。此外,您需要在Casting Objects.

上阅读更多内容

e.g。

String string = "String";

Object object = string; // Perfectly fine since String is an Object

String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.

答案 4 :(得分:0)

正确的方法是这样:

Integer i = Integer.cast(obj);

方法cast()是编译时强制转换的一种更安全的选择。