一尘不染

用Java转换变量

java

我想知道是否有人可以告诉我铸造的工作原理?我知道何时应该执行此操作,但并不真正了解它的工作原理。对于原始数据类型,我会部分理解,但是在涉及对象转换时,我不了解其工作方式。

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


阅读 379

收藏
2020-02-26

共1个答案

一尘不染

用Java进行转换并不是魔术,而是告诉编译器A类型的Object实际上是更特定的B类型,因此可以访问B本来没有的所有方法。在执行强制转换时,你没有执行任何魔术或转换操作,实际上是在告诉编译器“相信我,我知道我在做什么,并且我可以向你保证此行的此Object实际上是。” 例如:

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

以上很好,不是魔术,一切都很好。存储在o中的对象实际上是一个字符串,因此我们可以将其强制转换为字符串,而不会出现任何问题。

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

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

其次,如果它们处于相同的层次结构中,但仍然是无效的强制转换,则将ClassCastException在运行时抛出a :

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

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

为什么需要铸造?好吧,首先,只有在从更通用的类型转换为更具体的类型时才需要它。例如,Integer继承自Number,因此,如果你要存储一个Integeras,Number那么就可以了(因为所有的Integers都是Numbers。)但是,如果要沿相反的方向运行,则需要强制转换-并非所有Numbers都是Integers(同样作为整数我们有Double,Float,Byte,Long等),即使在你的项目或JDK只是一个子类,有人可以很容易地创建另一个和分发,所以,你不能保证,即使你认为这是一个单一的,显而易见的选择!

关于强制转换的使用,你仍然可以在某些库中看到对它的需求。在Java-5之前的版本中,它在集合和各种其他类中大量使用,因为所有集合都在添加对象,然后转换结果以使你退出集合。但是,随着泛型的出现,铸造的许多用途已不复存在-它已被泛型所取代,泛型提供了更安全的替代方法,而没有潜在的ClassCastExceptions(实际上,如果你干净地使用泛型并且编译时没有警告,你可以保证永远不会收到ClassCastException。)

2020-02-26