Есть ли предпочтение или разница в поведении между использованием:
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), вы можете использовать первый, чтобы быть более явным, если обозреватели кода продолжают спрашивать об этом.