提问人:user626912 提问时间:3/13/2011 最后编辑:ivanleonczuser626912 更新时间:2/20/2020 访问量:321374
在 Java 中转换变量
Casting variables in Java
问:
我想知道有没有人能告诉我选角是如何工作的?我明白什么时候应该这样做,但不知道它是如何工作的。关于原始数据类型,我部分理解,但是当涉及到转换对象时,我不明白它是如何工作的。
假设(只是一个例子)如何突然将 Object 类型的对象强制转换为,然后获取所有方法?MyType
答:
实际上,选角并不总是有效。如果对象不是要将其转换为的类,则在运行时将获得一个。instanceof
ClassCastException
仅当引用为该类型时,强制转换引用才有效。不能强制转换随机引用。另外,您需要阅读更多关于 铸造对象
.instanceof
例如
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.
在 Java 中强制转换不是魔术,而是你告诉编译器一个 A 类型的对象实际上是更具体的 B 类型,从而获得对 B 上所有方法的访问权,否则你就不会有这些方法。在执行强制转换时,您没有执行任何魔术或转换,您实际上是在告诉编译器“相信我,我知道我在做什么,我可以向您保证,这一行的这个对象实际上是一个<在此处插入强制转换类型>。例如:
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
这实质上意味着您违反了编译器的信任。你已经告诉它,你可以保证对象是特定类型的,但事实并非如此。
为什么需要铸造?好吧,首先,只有在从更通用的类型转到更具体的类型时才需要它。例如,继承自 ,所以如果你想将 存储为 ,那没关系(因为所有整数都是数字。然而,如果你想反过来,你需要一个转换 - 并非所有的数字都是整数(以及我们有的整数、、、等)。即使你的项目或 JDK 中只有一个子类,有人可以很容易地创建另一个子类并分发它,所以即使你认为这是一个单一的、显而易见的选择,你也无法保证!Integer
Number
Integer
Number
Double
Float
Byte
Long
关于用于铸造,您仍然在某些库中看到对它的需求。在 Java-5 之前,它被大量用于集合和其他各种类中,因为所有集合都致力于添加对象,然后转换你从集合中得到的结果。然而,随着泛型的出现,强制转换的大部分用途已经消失了 - 它已被泛型所取代,泛型提供了一种更安全的替代方案,而没有 ClassCastExceptions 的可能性(事实上,如果你干净地使用泛型并且它编译时没有警告,你可以保证你永远不会得到 ClassCastException。
评论
Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()
getLatitude()
Double
for (final Submodel submodel : submodels) { final NumericSubmodel numericSubmodel = (NumericSubmodel) submodel; ...}
假设你想将 a 转换为 a(是的,这没有任何意义),你不能直接转换它,因为该类不是子类,也不是该类的父类(编译器会抱怨)。String
File
File
String
但是你可以将你的 转换为 ,因为 a 是 ( 是父级)。然后,您可以将此对象转换为 ,因为 File 是 .String
Object
String
Object
Object
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
正确的方法是:
Integer i = Integer.class.cast(obj);
该方法是编译时强制转换更安全的替代方法。cast()
评论