我最近遇到了在进行object
检查之后将String
下放到instanceof
的代码。
Object obj = this.get(key);
if(obj instanceof String) {
return (String) object;
}
我对此有点困惑。我的理解是,它不适用于泛型,因为Type Erasure使实例不引用原始类。另外,我的理解(得到this answer的支持)是,在运行期间,向上转换为Object
与使用通用类型T
之间没有区别。这是否意味着instanceof
对于泛型无效的唯一原因是由于列出了here的编译时间检查?
instanceof运算符的RelationalExpression操作数的类型必须是引用类型或null类型;否则,将发生编译时错误。
如果在instanceof运算符之后提到的ReferenceType不表示可引用的引用类型(第4.7节),则是编译时错误。
如果将RelationalExpression强制转换为ReferenceType作为编译时错误,则关系表达式的instance同样会产生编译时错误。在这种情况下,instanceof表达式的结果永远不可能为真。
尽管如此,类似this question中的答案似乎暗示运行时行为有所不同。对象通常在运行时 do 包含类型信息,但是在泛型的情况下会被删除吗?在上播的情况下,如何删除类型信息?
希望有人可以识别我的知识差距在哪里。为了弄清我instanceof
here的行为,我做了一些阅读,但这超出了我的范围,我希望得到一个更直接的答案。
答案 0 :(得分:2)
对象始终知道它们的真正类型。
类型擦除意味着泛型在编译后的代码中“丢失”。例如。 List<String>
被编译成原始List
,在逻辑上等效于List<Object>
但是,将String
分配给声明为Object
的变量不会导致类型擦除,因为:
这不是通用的,因此类型擦除不适用。
该对象知道它是String
,而与变量的声明类型无关。
这就是为什么您可以问它:
您是字符串吗? x instanceof String
你是什么? x.getClass()