这两种 Java 中的类型转换方式有什么区别?

5

在Java中,这两种类型转换方式有什么区别?

  1. (CastingClass) objectToCast;

  2. CastingClass.class.cast(objectToCast);

Class#cast(Object)的源代码如下:

public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}

所以,cast基本上是强制转换操作的一种通用包装器,但我仍然不明白为什么需要一个方法来实现它。

好的,我刚意识到你可以使用 cast 将基本类型转换为其包装器。例如:Integer i = int.class.cast("1234"); - Ben Simmons
@simmbot:你可以“写”这个,但它不会做你最可能想做的事情。试试看。 - Pavel Minaev
这会抛出ClassCastException异常,因为String类型无法转换为Integer类型。在这种情况下,你需要使用Integer.valueOf("1234") - Ben Simmons
5个回答

7
你只能对静态链接类使用第一种形式。
在许多情况下,这是不够的-例如,您可能已经使用反射获得了类实例,或者它作为参数传递给您的方法;因此需要使用第二种形式。

正确。在第一种形式中,您正在源代码中“烘烤”转换。您无法在不重新编译的情况下更改它。第二种形式允许您尝试将其转换为任意类。 - Noel Ang

4

因为在泛型中,由于类型擦除,你不能直接写(T)objectToCast。虽然Java编译器允许这样做,但是T会被视为Object,所以即使你要转换的对象并不是T的实例,转换也总是会成功的。


嗨,Pavel,你能再解释一下吗?cast似乎就是这样做的:return (T) obj; - Ben Simmons
你绝对可以写那个。它仅会输出一个编译器警告。 - meriton
@meriton:说得好,已经编辑了。我的意思是,强制类型转换仍然不能真正实现它应该做的事情。 - Pavel Minaev
@simmbot: 它确实会执行显式类型检查,然后才进行强制类型转换(因为强制类型转换本身不会进行类型检查)。因此,它与普通的(Type)object强制类型转换一样类型安全-只有在对象实际上扩展或实现了“T”类型时,它才会返回“T”类型的引用,否则它将抛出异常。 - Pavel Minaev
@PavelMinaev 但是 "static" 转换 (Type)object 也是一样的。如果 object 不是 Type 的实例,那么会抛出 ClassCastException,对吧?那么这两种方式有什么区别呢? - Leonid Semyonov
区别在于您无法编写(T)object,其中T是通用类型参数,原因如上所述。 - Pavel Minaev

2
这是一个关于类型转换的讨论,涉及到两种不同的方法。第一种是普通的类型转换,需要在编译时知道要转换的类型。它会在编译时验证转换是否正确,并在运行时检查转换是否正确(如果要转换的类型不是泛型)。第二种方法使用反射API,需要在运行时知道要转换的类。它不会在编译时验证任何内容,但总是在运行时检查转换是否正确。
由于类型参数只在编译时知道,因此您无法对类型参数使用第二种方法(表达式“T.class”无法编译)。
动态加载的类(例如Class.forName(String))只在运行时知道,因此无法使用第一种方法。
编辑:然而,正如Pavel指出的那样,将对象转换为动态加载的类毫无意义。我同意Class.cast(Object)唯一真正有用的地方是将对象转换为您恰好拥有类对象的类型参数。
如果要转换的类型不包含类型参数,则第一种方法更好,因为额外的编译时检查可以捕获错误,您在运行时不会失去类型安全性,并且语法更短。

2
对于动态加载的类,你为什么需要强制转换呢?通常情况下,强制转换是为了让表达式具有某种类型,但在动态加载类的情况下,你事先不知道类型。毕竟,如果你有一个动态加载的类,你不知道调用Class<T>.cast()中的T是什么,所以你只能使用原始版本,然后返回类型将是Object - 并没有太多的强制转换。它会检查类型,但是Class.isInstance()肯定是更好的方法。总的来说,我认为这只适用于泛型。 - Pavel Minaev

1

在第一个中,您必须硬编码转换类。

( ClassToCast ) objectToCast;

在第二个中,转换类可能是一个参数:
Class toCast = getClassToCast();

toCast.cast( objectToCast );

0

这里,你可以找到一个使用示例,在其中使用了Class#cast()。它可能会给您带来新的见解。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接