为什么基于Class.class的转换工作但不是getClass?

use*_*530 10 java generics casting class

我有以下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);
  }
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么最后一个案例在前两个案例成功时失败了,为什么会出现这种情况?什么是更好的方法来实现这一目标?

man*_*uti 16

您需要指定类型参数Class:

Class<String> stringclass = (Class<String>) thetype.getClass();
Run Code Online (Sandbox Code Playgroud)

要么

Class<? extends String> stringclass = thetype.getClass();
Run Code Online (Sandbox Code Playgroud)

java.lang.Class.cast(Object obj) 将对象强制转换为此Class对象所表示的类或接口.

如果不指定类型,则不会告诉编译器Class实例表示哪个类或接口stringclass.

调用时String.class,Class对象将使用String类型进行隐式参数化.


Sot*_*lis 11

Java语言规范状态

类型C.class,C类,接口或数组类型(第4.3节)的类型是Class<C>.

所以表达式的类型

String.class
Run Code Online (Sandbox Code Playgroud)

Class<String>.Class是一个泛型类,其中方法cast在其返回类型中使用泛型类型变量.所以结果

String.class.cast(bar);
Run Code Online (Sandbox Code Playgroud)

是类型的表达式T,其中,T已经被绑定到String在该调用.

返回类型Object#getClass()Class<? extends T>T其上调用的表达式的擦除类型.

在这种情况下,就是这样

Class<? extends String>
Run Code Online (Sandbox Code Playgroud)

但是,您将其分配给原始参考.

Class stringclass = thetype.getClass();
Run Code Online (Sandbox Code Playgroud)

由于变量stringclassraw,因此将删除依赖于泛型类型变量的方法的任何用法.

所以Class#cast(Object)现在有一个返回类型,Object它不能赋值给String变量.

你做完了吗

Class<? extends String> stringclass = thetype.getClass();
Run Code Online (Sandbox Code Playgroud)

你没事.