下面哪个比较好?
a instanceof B
or
B.class.isAssignableFrom(a.getClass())
我所知道的唯一区别是,当'a'为空时,第一个返回false,而第二个抛出异常。除此之外,它们总是给出相同的结果吗?
下面哪个比较好?
a instanceof B
or
B.class.isAssignableFrom(a.getClass())
我所知道的唯一区别是,当'a'为空时,第一个返回false,而第二个抛出异常。除此之外,它们总是给出相同的结果吗?
当前回答
还有一个不同之处。如果要测试的类型(Class)是动态的,例如,作为方法参数传递,那么instanceof将不会为你切割它。
boolean test(Class clazz) {
return (this instanceof clazz); // clazz cannot be resolved to a type.
}
但是你可以:
boolean test(Class clazz) {
return (clazz.isAssignableFrom(this.getClass())); // okidoki
}
哎呀,这个答案已经讲过了。也许这个例子对某人有帮助。
其他回答
除了上面提到的基本区别之外,在类中的instanceof操作符和isAssignableFrom方法之间还有一个核心的微妙区别。
Read instanceof as “is this (the left part) the instance of this or any subclass of this (the right part)” and read x.getClass().isAssignableFrom(Y.class) as “Can I write X x = new Y()”. In other words, instanceof operator checks if the left object is same or subclass of right class, while isAssignableFrom checks if we can assign object of the parameter class (from) to the reference of the class on which the method is called. Note that both of these consider the actual instance not the reference type.
考虑一个A、B和C三个类的例子,其中C扩展了B, B扩展了A。
B b = new C();
System.out.println(b instanceof A); //is b (which is actually class C object) instance of A, yes. This will return true.
System.out.println(b instanceof B); // is b (which is actually class C object) instance of B, yes. This will return true.
System.out.println(b instanceof C); // is b (which is actually class C object) instance of C, yes. This will return true. If the first statement would be B b = new B(), this would have been false.
System.out.println(b.getClass().isAssignableFrom(A.class));//Can I write C c = new A(), no. So this is false.
System.out.println(b.getClass().isAssignableFrom(B.class)); //Can I write C c = new B(), no. So this is false.
System.out.println(b.getClass().isAssignableFrom(C.class)); //Can I write C c = new C(), Yes. So this is true.
还有另一个区别:
不管X是什么,null instanceof X都是假的
null.getClass().isAssignableFrom(X)将抛出NullPointerException
Instanceof只能用于引用类型,不能用于基本类型。isAssignableFrom()可以用于任何类对象:
a instanceof int // syntax error
3 instanceof Foo // syntax error
int.class.isAssignableFrom(int.class) // true
看到http://java.sun.com/javase/6/docs/api/java/lang/Class.html isAssignableFrom (. lang . class)。
用一些例子来证明它怎么样?
@Test
public void isInstanceOf() {
Exception anEx1 = new Exception("ex");
Exception anEx2 = new RuntimeException("ex");
RuntimeException anEx3 = new RuntimeException("ex");
//Base case, handles inheritance
Assert.assertTrue(anEx1 instanceof Exception);
Assert.assertTrue(anEx2 instanceof Exception);
Assert.assertTrue(anEx3 instanceof Exception);
//Other cases
Assert.assertFalse(anEx1 instanceof RuntimeException);
Assert.assertTrue(anEx2 instanceof RuntimeException);
Assert.assertTrue(anEx3 instanceof RuntimeException);
}
@Test
public void isAssignableFrom() {
Exception anEx1 = new Exception("ex");
Exception anEx2 = new RuntimeException("ex");
RuntimeException anEx3 = new RuntimeException("ex");
//Correct usage = The base class goes first
Assert.assertTrue(Exception.class.isAssignableFrom(anEx1.getClass()));
Assert.assertTrue(Exception.class.isAssignableFrom(anEx2.getClass()));
Assert.assertTrue(Exception.class.isAssignableFrom(anEx3.getClass()));
//Incorrect usage = Method parameter is used in the wrong order
Assert.assertTrue(anEx1.getClass().isAssignableFrom(Exception.class));
Assert.assertFalse(anEx2.getClass().isAssignableFrom(Exception.class));
Assert.assertFalse(anEx3.getClass().isAssignableFrom(Exception.class));
}
这个帖子让我了解了instanceof与isAssignableFrom的不同之处,所以我想分享一下我自己的一些内容。
我发现使用isAssignableFrom是唯一的(可能不是唯一的,但可能是最简单的)方法来询问自己一个类的引用是否可以接受另一个类的实例,当一个类的实例都没有时进行比较。
因此,当我只有类时,我不认为使用instanceof操作符比较可赋值性是一个好主意,除非我打算从其中一个类创建一个实例;我觉得这样会很草率。