[Java] instanceof和Class.isAssignableFrom(...)有什麼區別?


Answers

instanceof只能用於引用類型,而不能用於基本類型。 isAssignableFrom()可以用於任何類對象:

a instanceof int  // syntax error
3 instanceof Foo  // syntax error
int.class.isAssignableFrom(int.class)  // true

請參閱

Question

以下哪項更好?

a instanceof B

要么

B.class.isAssignableFrom(a.getClass())

我所知道的唯一區別是,當'a'為空時,第一個返回false,第二個拋出異常。 除此之外,他們總是給出相同的結果嗎?




instanceof不能與原始類型或泛型類型一起使用。 如下面的代碼所示:

//Define Class< T > type ... 

Object e = new Object();

if(e instanceof T) {
  // Do something.
}

錯誤是:無法對類型參數T執行instanceof檢查。使用它的擦除對象,因為進一步的通用類型信息將在運行時被擦除。

由於刪除運行時引用而進行類型擦除,因此不進行編譯。 但是,下面的代碼將被編譯:

if( type.isAssignableFrom(e.getClass())){
  // Do something.
}



這個線程為我提供了一些有關instanceofisAssignableFrom不同的isAssignableFrom ,所以我想我會分享一些我自己的東西。

我發現使用isAssignableFrom是唯一的(可能不是唯一的,但可能是最簡單的)方式來詢問自己,如果一個類的引用可以帶有另一個類的實例,那麼當一個類沒有實例進行比較的實例時。

因此,我沒有發現使用instanceof運算符來比較賦值是否是一個好主意,當我所有的都是類時,除非我考慮從其中一個類創建實例; 我認為這將是sl。。




更直接的等價於a instanceof B

B.class.isInstance(a)

這也適用(返回false),當a也是null




表現“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

所以我們可以得出結論: instanceofisInstance()isAssignableFrom()相差不遠(+ 0.9%的執行時間)。 所以無論你選擇什麼,都沒有真正的區別




還有另一個區別:

無論X是什麼,null的instanceof X都是false

null.getClass()。isAssignableFrom(X)將拋出一個NullPointerException