在getClass()文档中"删除它所称的表达式的静态类型"是什么意思?

Sco*_*ter 10 java

Object 的"public final Class <?> getClass()"方法的文档说:

实际的结果类型是Class <?extends | X |> where | X | 是调用getClass的表达式的静态类型的擦除.例如,此代码片段中不需要强制转换:

我不明白这个解释,特别是关于什么| X | 据说 - "擦除了调用getClass的表达式的静态类型".

什么形式的符号是| X | ?或者,也许,其他地方| X | 是否使用了表示法?

Kat*_*ona 7

让我们考虑以下示例:

List<Integer> test = new ArrayList<Integer>();
Class<? extends List> clazz = test.getClass();
Run Code Online (Sandbox Code Playgroud)

test(the expression on which getClass() is called)的静态类型是List<Integer>擦除List(参见类型擦除).请注意,动态(或运行时)类型testArrayList,并且运行时类型clazz将是Class<ArrayList>.

所以,Class<? extends |X|>在这种情况下是Class<? extends List>.


mer*_*ike 7

Java语言规范要求编译器以特殊方式处理此方法:

该方法getClass返回表示Class对象类的对象.

Class每个引用类型都存在一个对象.例如,它可用于发现类的完全限定名称,其成员,直接超类以及它实现的任何接口.

类型的getClass的方法调用表达式的是Class<? extends |T|>,其中T在所述类或接口搜寻(§15.12.1)为的getClass.

所以getClass的返回类型getClass()是调用表达式的静态(编译时)类型.例如:

String s = "";
Object o = s;
Class<? extends String> sc = s.getClass(); // ok
Class<? extends Object> oc = o.getClass(); // ok
oc = sc; // ok
sc = o.getClass(); // not ok
sc = oc; // not ok
Run Code Online (Sandbox Code Playgroud)

记号|X|定义在规格如下:

类型擦除是从类型(可能包括参数化类型和类型变量)到类型(从不参数化类型或类型变量)的映射.我们写|T|的是类型的擦除T.擦除映射定义如下:

  • 参数化类型(第4.5节)的擦除G<T1,...,Tn>|G|.

  • 嵌套类型的擦除T.C|T|.C.

  • 数组类型的擦除T[]|T|[].

  • 类型变量(第4.4节)的擦除是其最左边界的擦除.

  • 每种其他类型的擦除都是类型本身.

例如,如果我们有:

List<String> list = ...;    
Run Code Online (Sandbox Code Playgroud)

表达式list.getClass()是类型Class<? extends List>而不是Class<? extends List<String>>.