在Java中投射variables

我想知道有没有人可以告诉我如何铸造工程? 我明白什么时候该做,但不是真的如何。 对于原始数据types我理解了一些,但是当涉及到投射对象时,我不明白它是如何工作的。

一个Objecttypes的对象怎么会突然被抛出,比方说MyType (仅仅是一个例子),然后得到所有的方法?

使用Java进行投射并不神奇,因为您告诉编译器,Atypes的对象实际上是更具体的typesB,因此可以访问B中所有您不会拥有的方法。 在执行转换时,你并没有执行任何types的魔法或转换,你基本上是告诉编译器“相信我,我知道我在做什么,我可以保证这个对象在这一行实际上是一个<Insert cast在这里键入>“。 例如:

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

以上是好的,不是魔术,一切都好。 存储在o中的对象实际上是一个string,因此我们可以将其转换为一个没有任何问题的string。

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

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

其次,如果它们处于相同的层次结构中,但仍然是无效的转换,那么将在运行时引发ClassCastException

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

这基本上意味着你违反了编译器的信任。 你已经告诉它,你可以保证对象是一个特定的types,而不是。

为什么你需要铸造? 那么,首先你只需要从更一般的types到更具体的types。 例如, IntegerNumberinheritance,所以如果你想存储一个Integer作为一个Number那么没关系(因为所有的整数都是Numbers)。但是,如果你想转到另一个方向,你需要一个转换 – 不是所有的Nu​​mbers都是整数(以及Integer,我们有DoubleFloatByteLong等)即使项目或JDK中只有一个子类,也可以轻易地创build另一个子类来分发它,所以即使你认为这是一个明显的select!

关于使用铸造,你仍然在一些图书馆看到它的需要。 在Java-5之前,它在集合和各种其他类中被大量使用,因为所有集合都在添加对象,然后将结果返回到集合中。 然而,随着generics的出现,大部分的用于铸造的东西已经消失了 – 它已经被generics所替代,它提供了一个更安全的select,而没有ClassCastExceptions的潜力(事实上,如果你使用generics并且没有警告,你有一个保证,你永远不会得到一个ClassCastException。)

其实,铸造并不总是工作。 如果该对象不是您正在将其投射到的类的instanceof ,则将在运行时获得ClassCastException

假设你想把一个string转换成一个文件(是的,它没有任何意义),你不能直接转换它,因为File类不是一个孩子,而不是String类的父亲(和编译器抱怨)。 但是你可以把你的string转换为对象,因为一个string是一个对象(对象是父对象)。 那么你可以将这个对象转换成一个文件,因为一个文件是一个对象。 因此,在编译时从打字的angular度来看,所有的操作都是“合法的”,但这并不意味着它在运行时就会起作用!

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

即使编译器没有意义,编译器也会允许这样做,但在运行时会发生这种exception:

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

只有它是一个该types的instanceof ,才能使用引用。 你不能投射随机引用。 此外,你需要阅读更多关于Casting Objects

例如

 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.