提问人:Johan Lübcke 提问时间:6/1/2010 最后编辑:jscsJohan Lübcke 更新时间:8/4/2022 访问量:340123
在调用 instanceof 之前是否需要进行 null 检查?
Is null check needed before calling instanceof?
答:
使用 null 引用作为第一个操作数返回 。instanceof
false
评论
!null
instanceof
false
!null
不,不是。 如果它的第一个操作数是 ,则返回。instanceof
false
null
不,在使用 instanceof 之前不需要进行 null 检查。
表达式为 if is 。x instanceof SomeClass
false
x
null
Java 11 语言规范在第 15.20.2 节 “类型比较运算符 instanceof” 中简明扼要地表达了这一点。(Java 17 在引入 instanceof patternmatching 之后,就不那么简洁地表达了这一点。
“在运行时,运算符的结果是,如果 RelationalExpression 的值为 不
为 null
,引用可以是 强制转换为 ReferenceType,而不引发 . 否则结果是。instanceof
true
ClassCastException
false
因此,如果操作数为 null,则结果为 false。
评论
try it
Effective Java
确实是非常好的问题。我只是自己试过。
public class IsInstanceOfTest {
public static void main(final String[] args) {
String s;
s = "";
System.out.println((s instanceof String));
System.out.println(String.class.isInstance(s));
s = null;
System.out.println((s instanceof String));
System.out.println(String.class.isInstance(s));
}
}
指纹
true
true
false
false
JLS / 15.20.2。类型比较运算符 instanceof
在运行时,运算符的结果是,如果 RelationalExpression 的值不是,则可以将引用强制转换为 ReferenceType,而不会引发 .否则,结果是 。
instanceof
true
null
ClassCastException
false
如果此对象表示接口,则此方法返回指定参数的类或任何超类是否实现此接口;否则返回。如果此对象表示基元类型,则此方法返回 。
Class
true
Object
false
Class
false
评论
s
""
null
null
s instanceof String
field.getType().equals(String.class)
s instanceof String
s
"" instanceof String
null instanceof String
运算符不需要显式检查,因为如果操作数为 ,则它不会抛出 。instanceof
null
NullPointerException
null
在运行时,如果关系表达式的值不是,则运算符的结果为 true,并且可以将引用强制转换为引用类型,而不会引发类强制转换异常。instanceof
null
如果操作数为 ,则运算符返回,因此不需要显式 null 检查。null
instanceof
false
请看下面的例子,
public static void main(String[] args) {
if(lista != null && lista instanceof ArrayList) { //Violation
System.out.println("In if block");
}
else {
System.out.println("In else block");
}
}
的正确用法如下图所示,instanceof
public static void main(String[] args) {
if(lista instanceof ArrayList){ //Correct way
System.out.println("In if block");
}
else {
System.out.println("In else block");
}
}
就像一个花絮:
甚至 ((A)null)
将返回 。(
instanceof A)
false
(如果类型转换看起来令人惊讶,有时你必须这样做,例如在这样的情况下:null
public class Test
{
public static void test(A a)
{
System.out.println("a instanceof A: " + (a instanceof A));
}
public static void test(B b) {
// Overloaded version. Would cause reference ambiguity (compile error)
// if Test.test(null) was called without casting.
// So you need to call Test.test((A)null) or Test.test((B)null).
}
}
所以会打印。Test.test((A)null)
a instanceof A: false
P.S.:如果你正在招聘,请不要把这个作为面试问题。:D
评论
- 在 instanceof 之前不需要 null 检查
- 在验证为 true 的 instanceof 之后,不需要 null 检查
以下是 null 安全的:
if(couldbenull instanceof Comparable comp){
return comp.compareTo(somethingElse);
}
//java < 14
if(couldbenull instanceof Comparable){
return ((Comparable)couldbenull).compareTo(somethingElse);
}
不,在调用 之前不需要检查。如果其值为 ,则始终返回 false。null
instanceof
null
根据 Java 语言规范,使用 .instanceof
在运行时,如果 RelationalExpression 的值不为 null,引用可以 转换为 ReferenceType,而不引发 ClassCastException。 否则结果为 false
因此,我们可以推断 java 也有一种叫做类型的东西,并且这个 null 类型在运算符中被检查,这显然返回 false,因为它需要一个特定的类型。null
instanceof
Java 编程语言中有两种类型:原始类型和引用类型。 根据 Java 类型和值规范
还有一个特殊的 null 类型,表达式 null 的类型, 它没有名字。因为 null 类型没有名称,所以不可能 声明 null 类型的变量或强制转换为 null 类型。 null 引用是 null 表达式的唯一可能值 类型。空参照始终可以进行加宽参照 转换为任何引用类型。
从 Java 14 开始,尤其是在 LTS Java 17 中,我们有一个增强的 .我们有模式匹配功能,可以在类型比较后执行强制转换。instanceof
例
public static void main(String[] args) {
Object testObject = "I am a string";
List<Object> testList = null;
if (testList instanceof List) {
System.out.println("instance of list");
} else {
System.out.println("null type");
}
//Enhanced instanceof with type conversion - tested with JDK 17
if (testObject instanceof String str) {
System.out.println(str.toUpperCase());
}
}
输出
null type
I AM A STRING
评论
instanceof
null
equals()