Есть ли предпочтение или разница в поведении между использованием:
if(obj.getClass().isArray()) {}
и
if(obj instanceof Object[]) {}
?
Есть ли предпочтение или разница в поведении между использованием:
if(obj.getClass().isArray()) {}
и
if(obj instanceof Object[]) {}
?
В общем случае используйте оператор instanceof
для проверки того, является ли объект массивом.
На уровне JVM оператор instanceof
переводит на определенный байтовый код "instanceof" , который сильно оптимизирован в большинстве реализаций JVM.
Отражательный подход (getClass().isArray()
) скомпилирован в две отдельные инструкции "invokevirtual" . Более общие оптимизации, применяемые JVM к ним, могут быть не такими быстрыми, как оптимизированные вручную оптимизаторы, присущие инструкции "instanceof".
Существует два особых случая: нулевые ссылки и ссылки на примитивные массивы.
Нулевая ссылка вызовет instanceof
результат false
, а isArray
выдает a NullPointerException
.
Применяется к примитивному массиву, instanceof
дает false
, если правый операнд точно не соответствует типу компонента. Напротив, isArray()
вернет true
для любого типа компонента.
В последнем случае, если obj равно null, вы не получите исключение NullPointerException, а false.
Если obj
имеет тип int[]
, скажем, тогда у него будет массив Class
, но не будет экземпляром Object[]
. Итак, что вы хотите сделать с obj
. Если вы собираетесь бросить его, перейдите к instanceof
. Если вы собираетесь использовать отражение, используйте .getClass().isArray()
.
getClass().isArray()
значительно медленнее на Sun Java 5 или 6 JRE, чем на IBM.
Так много, что с помощью clazz.getName().charAt(0) == '['
работает быстрее на Sun JVM.
Недавно я столкнулся с проблемой обновления приложения Groovy от JDK 5 до JDK 6. Использование isArray()
не удалось в JDK6:
MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
Изменение на instanceof Object[]
исправлено.
Отражение массива Java - это случай, когда у вас нет экземпляра класса, доступного для включения "instanceof". Например, если вы пишете какую-то инфраструктуру инъекций, которая вводит значения в новый экземпляр класса, например, JPA, то вам нужно использовать функцию isArray().
Я писал об этом раньше в декабре. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Если у вас когда-либо есть выбор между рефлексивным решением и неотражающим решением, никогда не выбирайте отражающий (включая объекты класса). Это не значит, что это "неправильно" или что-то еще, но все, что связано с отражением, вообще менее очевидно и менее понятно.
Нет разницы в поведении, которое я могу найти между ними (кроме очевидного нулевого случая). Что касается того, какую версию предпочесть, я бы пошел со вторым. Это стандартный способ сделать это в Java.
Если это смущает читателей вашего кода (потому что String[] instanceof Object[]
is true), вы можете использовать первый, чтобы быть более явным, если обозреватели кода продолжают спрашивать об этом.