需要有关 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
因为 String
和 Integer
都是 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
的子类型
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" 归类为编译错误。
当我键入 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
因为 String
和 Integer
都是 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
RelationalExpression: ... RelationalExpression instanceof ReferenceType
If a cast of the
RelationalExpression
to theReferenceType
would be rejected as a compile-time error (§15.16), then theinstanceof
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" 归类为编译错误。