下面哪个比较好?
a instanceof B
or
B.class.isAssignableFrom(a.getClass())
我所知道的唯一区别是,当'a'为空时,第一个返回false,而第二个抛出异常。除此之外,它们总是给出相同的结果吗?
下面哪个比较好?
a instanceof B
or
B.class.isAssignableFrom(a.getClass())
我所知道的唯一区别是,当'a'为空时,第一个返回false,而第二个抛出异常。除此之外,它们总是给出相同的结果吗?
当前回答
Instanceof也不能用于基本类型或泛型类型。如下代码所示:
//Define Class< T > type ...
Object e = new Object();
if(e instanceof T) {
// Do something.
}
错误是:不能对类型参数t执行instanceof检查,而是使用它的erasure对象,因为进一步的泛型类型信息将在运行时被擦除。
由于删除运行时引用的类型擦除而无法编译。然而,下面的代码将编译:
if( type.isAssignableFrom(e.getClass())){
// Do something.
}
其他回答
在性能“2”方面(与JMH):
class A{}
class B extends A{}
public class InstanceOfTest {
public static final Object a = new A();
public static final Object b = new B();
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public boolean testInstanceOf()
{
return b instanceof A;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public boolean testIsInstance()
{
return A.class.isInstance(b);
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public boolean testIsAssignableFrom()
{
return A.class.isAssignableFrom(b.getClass());
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(InstanceOfTest.class.getSimpleName())
.warmupIterations(5)
.measurementIterations(5)
.forks(1)
.build();
new Runner(opt).run();
}
}
它给:
Benchmark Mode Cnt Score Error Units
InstanceOfTest.testInstanceOf avgt 5 1,972 ? 0,002 ns/op
InstanceOfTest.testIsAssignableFrom avgt 5 1,991 ? 0,004 ns/op
InstanceOfTest.testIsInstance avgt 5 1,972 ? 0,003 ns/op
因此,我们可以得出结论:instanceof as fast as isInstance() and isAssignableFrom() not far(+0.9%的执行时间)。所以无论你选择什么都没有真正的区别
这完全取决于代码中此时可用的内容。我不建议使用isAssignableFrom如果你正在使用一个实际的对象-有一个更好的选择。下面是一份根据你所拥有的产品进行排名的推荐列表:
如果你有一个对象a,并且你在编译时知道类型B: a instanceof实例 如果你有一个对象a,你不知道类型B,但你有一个对象B: .isInstance b.getClass () () 如果你有一个对象a,在编译时没有类型或实例化对象,但你有一个类对象class <?> someBClass: someBClass.isInstance (a) 如果你没有实例化对象,但是你有两个Class<?>对象: someBClass.isAssignableFrom (someAClass)。
假设你从列表的顶部开始,然后往下做,每一种方法都是实现目标的最简单的方法,根据我自己的研究,我相信你也会得到最好的表现。
isAssignableFrom(A, B) =
if (A == B) return true
else if (B == java.lang.Object) return false
else return isAssignableFrom(A, getSuperClass(B))
The pseudo code above is a definition of, if references of type/class A is assignable from references of type/class B. It is a recursive definition. To some it may be helpful, for others it may be confusing. I add it in case somebody should find it useful. This is just an attempt to capture my understanding, it is not the official definition. It is used in a certain Java VM implementation and works for many example programs, so while I cannot guarentee that it captures all aspects of isAssignableFrom, it is not completely off.
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)。
在使用instanceof时,您需要在编译时知道B的类。当使用isAssignableFrom()时,它可以是动态的,并在运行时更改。