需要有关 Instanceof Operator 中类型转换的信息

Needs information regarding type casting in Instanceof Operator

当我键入 cast string to Object 时,以下 instanceof 运算符工作正常。

但是,如果不进行类型转换,编译将失败。

public class Test {
        public static void main(String[] args) {
            boolean b1 = "abc" instanceof Integer; // Compilation fails
            boolean b2 = ((Object) "abc") instanceof Integer; // Works fine
        }
    }

我的问题是为什么编译器拒绝第一个 b1 而允许第二个 b2

因为您已将 "abc" 强制转换为 Object,编译器将 ((Object) "abc") 视为与任何其他 Object 类型的表达式相同。

因此,它认为它可以包含任何 Object(或 null)。编译器不会深入检查表达式以确定更具体的类型。

你也可以这样写:

Object obj = "abc";
boolean b2 = obj instanceof Integer;

基本一样

它会阻止你写 "abc" instanceof Integer 因为 StringInteger 都是 class,而且它们是不相关的,所以 String 永远不可能Integer 的实例。 (它允许 "abc" instanceof List,因为 List 是一个接口,它不考虑 class 的 final-ness,并假设可能有一个 subclass 的 String 可以实现 List).

从某种意义上说,转换就是告诉编译器你知道的比它知道的多。尽管编译器能够在非常基本的情况下推回它可以确定您正在做一些荒谬的事情,但它在很大程度上会避开并信任您(以 "on your head be it" 的方式)。

instanceof只能在父子之间使用类

第一个"abc"是String类型,不是Integer。
但是第二个 ((Object) "abc") 是 Object 类型,Integer 是 Object

的子类型

JLS 15.20 and 15.20.2 说明:

RelationalExpression:
  ...
  RelationalExpression instanceof ReferenceType

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error (§15.16), then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

在您的第一个示例中,表达式 ("abc" instanceof Integer) "abc" (a String) 无法转换为 Integer。因此 instanceof 表达式是一个编译错误。

在您的第二个示例表达式 (((Object) "abc") instanceof Integer) 中,左操作数的类型为 Object。在某些情况下,Object 可能是 Integer。因此 left-hand 操作数 可以 转换为 right-hand 类型。因此 instanceof 是允许的。

值得注意的是,JLS 只关心表达式的 compile-time 类型。在第二个例子中,我们可以很容易地推断出左手操作数的 run-time 类型总是 String 并且表达式的计算结果总是 false。但是 JLS 规则不会将此 "mistake" 归类为编译错误。