我有以下3项测试。前两个工作,最后一个没有。我提出这个问题的动机是,我希望能够转换对象A
,使其与对象B
具有相同的类,当A
已知为子类型时B
。
@Test
public void testWorks() {
Object bar = "foobar";
String blah = (String) bar;
System.out.println(blah); // Outputs foobar
}
@Test
public void testAlsoWorks() {
Object bar = "helloworld";
String blah = String.class.cast(bar);
System.out.println(blah); // Outputs helloworld
}
@Test
public void testfails() {
Object bar = "foobar";
String thetype = "hello";
Class stringclass = thetype.getClass();
String blah = stringclass.cast(bar); // Compiler error: incompatible types: Object cannot be converted to String
System.out.println(blah);
}
任何人都可以解释为什么最后一个案例在前两个案件成功时失败了,为什么会出现这种情况?什么是更好的方法来实现这一目标?
答案 0 :(得分:16)
您需要指定Class
的类型参数:
Class<String> stringclass = (Class<String>) thetype.getClass();
或
Class<? extends String> stringclass = thetype.getClass();
java.lang.Class.cast(Object obj)
将一个对象强制转换为此Class对象所代表的类或接口。
如果没有指定类型,则不会告诉编译器Class
实例stringclass
表示哪个类或接口。
当您致电String.class
时,Class
对象会使用String
类型进行隐式参数化。
答案 1 :(得分:11)
C.class
的类型,其中C
是类,接口或的名称 数组类型(§4.3),是Class<C>
。
所以表达式的类型
String.class
是Class<String>
。 Class
是一个泛型类,其中方法cast
在其返回类型中使用泛型类型变量。所以
String.class.cast(bar);
是T
类型的表达式,其中T
已在此调用中绑定到String
。
Object#getClass()
的返回类型为Class<? extends T>
,其中T
是其调用的表达式的已删除类型。
在这种情况下,那是
Class<? extends String>
但是,您要将其分配给原始参考。
Class stringclass = thetype.getClass();
由于变量stringclass
为raw, any uses of its methods that depend on the generic type variable are erased.
所以Class#cast(Object)
现在的返回类型为Object
,不能分配给String
变量。
你做完了
Class<? extends String> stringclass = thetype.getClass();
你会好的。