В чем разница между instanceof и Class.isAssignableFrom (...)? - PullRequest
428 голосов
/ 30 января 2009

Что из следующего лучше?

a instanceof B

или

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

Единственное различие, о котором я знаю, это то, что, когда 'a' равно нулю, первое возвращает false, а второе выдает исключение. Кроме этого, они всегда дают один и тот же результат?

Ответы [ 13 ]

0 голосов
/ 20 августа 2017

Разговор с точки зрения производительности "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 так же быстро, как isInstance () и isAssignableFrom () недалеко (+ 0,9% времени выполнения). Так что нет никакой разницы, что бы вы ни выбрали

0 голосов
/ 18 марта 2016
isAssignableFrom(A, B) =

if (A == B) return true
else if (B == java.lang.Object) return false
else return isAssignableFrom(A, getSuperClass(B))

Приведенный выше псевдокод является определением, если ссылки типа / класса A можно назначить из ссылок типа / класса B. Это рекурсивное определение. Для некоторых это может быть полезно, для других это может сбивать с толку. Я добавляю это на тот случай, если кто-то найдет это полезным. Это просто попытка поймать мое понимание, это не официальное определение. Он используется в определенной реализации Java VM и работает для многих примеров программ, поэтому хотя я не могу гарантировать, что он охватывает все аспекты isAssignableFrom, он не полностью отключен.

0 голосов
/ 25 августа 2010

некоторые тесты, которые мы провели в нашей команде, показывают, что A.class.isAssignableFrom(B.getClass()) работает быстрее, чем B instanceof A. это может быть очень полезно, если вам нужно проверить это на большом количестве элементов.

...