Отражение массива Java: isArray vs. instanceof

Есть ли предпочтение или разница в поведении между использованием:

if(obj.getClass().isArray()) {}

и

if(obj instanceof Object[]) {}

?

Ответ 1

В общем случае используйте оператор instanceof для проверки того, является ли объект массивом.

На уровне JVM оператор instanceof переводит на определенный байтовый код "instanceof" , который сильно оптимизирован в большинстве реализаций JVM.

Отражательный подход (getClass().isArray()) скомпилирован в две отдельные инструкции "invokevirtual" . Более общие оптимизации, применяемые JVM к ним, могут быть не такими быстрыми, как оптимизированные вручную оптимизаторы, присущие инструкции "instanceof".

Существует два особых случая: нулевые ссылки и ссылки на примитивные массивы.

Нулевая ссылка вызовет instanceof результат false, а isArray выдает a NullPointerException.

Применяется к примитивному массиву, instanceof дает false, если правый операнд точно не соответствует типу компонента. Напротив, isArray() вернет true для любого типа компонента.

Ответ 2

В последнем случае, если obj равно null, вы не получите исключение NullPointerException, а false.

Ответ 3

Если obj имеет тип int[], скажем, тогда у него будет массив Class, но не будет экземпляром Object[]. Итак, что вы хотите сделать с obj. Если вы собираетесь бросить его, перейдите к instanceof. Если вы собираетесь использовать отражение, используйте .getClass().isArray().

Ответ 4

getClass().isArray() значительно медленнее на Sun Java 5 или 6 JRE, чем на IBM.

Так много, что с помощью clazz.getName().charAt(0) == '[' работает быстрее на Sun JVM.

Ответ 5

Недавно я столкнулся с проблемой обновления приложения Groovy от JDK 5 до JDK 6. Использование isArray() не удалось в JDK6:

MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...

Изменение на instanceof Object[] исправлено.

Ответ 6

Отражение массива Java - это случай, когда у вас нет экземпляра класса, доступного для включения "instanceof". Например, если вы пишете какую-то инфраструктуру инъекций, которая вводит значения в новый экземпляр класса, например, JPA, то вам нужно использовать функцию isArray().

Я писал об этом раньше в декабре. http://blog.adamsbros.org/2010/12/08/java-array-reflection/

Ответ 7

Если у вас когда-либо есть выбор между рефлексивным решением и неотражающим решением, никогда не выбирайте отражающий (включая объекты класса). Это не значит, что это "неправильно" или что-то еще, но все, что связано с отражением, вообще менее очевидно и менее понятно.

Ответ 8

Нет разницы в поведении, которое я могу найти между ними (кроме очевидного нулевого случая). Что касается того, какую версию предпочесть, я бы пошел со вторым. Это стандартный способ сделать это в Java.

Если это смущает читателей вашего кода (потому что String[] instanceof Object[] is true), вы можете использовать первый, чтобы быть более явным, если обозреватели кода продолжают спрашивать об этом.