Есть ли предпочтения или различия в поведении между использованием:
if(obj.getClass().isArray()) {}
и
if(obj instanceof Object[]) {}
?
Есть ли предпочтения или различия в поведении между использованием:
if(obj.getClass().isArray()) {}
и
if(obj instanceof Object[]) {}
?
Ответы:
В большинстве случаев вы должны использовать instanceofоператор, чтобы проверить, является ли объект массивом.
Как правило, вы проверяете тип объекта, прежде чем переходить к определенному типу, который известен во время компиляции. Например, возможно, вы написали некоторый код, который может работать с Integer[]или int[]. Вы бы хотели охранять свои заклинания с помощью instanceof:
if (obj instanceof Integer[]) {
Integer[] array = (Integer[]) obj;
/* Use the boxed array */
} else if (obj instanceof int[]) {
int[] array = (int[]) obj;
/* Use the primitive array */
} else ...
На уровне JVM instanceofоператор выполняет преобразование в определенный байт-код instanceof , который оптимизирован в большинстве реализаций JVM.
В более редких случаях вы можете использовать отражение для обхода графа объектов неизвестных типов. В подобных случаях isArray()метод может быть полезен, потому что вы не знаете тип компонента во время компиляции; вы можете, например, реализовать какой-то механизм сериализации и иметь возможность передавать каждый компонент массива к одному и тому же методу сериализации, независимо от типа.
Есть два особых случая: нулевые ссылки и ссылки на примитивные массивы.
Нулевая ссылка приведет instanceofк результату false, пока isArrayвыбрасывает a NullPointerException.
Применительно к примитивному массиву instanceofвыдает результат, falseесли только тип компонента в правом операнде точно не соответствует типу компонента. Напротив, isArray()вернется trueдля любого типа компонента.
obj instanceof int[]урожаи , falseкогда вы назначаете int[]к obj, вы ошибаетесь.
obj instanceof Object[]дает, falseесли Object obj = new int[7].
java.lang.Object, так что это имеет смысл. Но instanceofвсе еще может использоваться для проверки примитивных массивов.
isArray()следует использовать вызовы . В очень не общем частном случае наличия только массивов объектов instanceofобеспечивает высокую производительность альтернативы.
Если 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[]исправить это.
isArrayэто метод Class, нет Type, поэтому, конечно GenericArrayTypeImpl, не имеет этот метод. И getClassникогда не сможет вернуть не- Class Type, так что вы (или Groovy ??), должно быть, сделали что-то не так, чтобы получить это, например, предположив, что каждый Type- это Class.
Отражение массива Java предназначено для случаев, когда у вас нет экземпляра Class, доступного для выполнения instanceof. Например, если вы пишете какую-то инфраструктуру внедрения, которая внедряет значения в новый экземпляр класса, такой как JPA, то вам нужно использовать функциональность isArray ().
Я писал об этом в начале декабря. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Если у вас когда-либо есть выбор между отражающим решением и неотражающим решением, никогда не выбирайте отражающее решение (включая объекты класса). Дело не в том, что это «неправильно» или что-то в этом роде, но все, что связано с отражением, обычно менее очевидно и менее ясно.
Нет никакой разницы в поведении, которое я могу найти между этими двумя (кроме очевидного нулевого случая). Что касается какой версии отдать предпочтение, я бы пошел со второй. Это стандартный способ сделать это в Java.
Если это смущает читателей вашего кода (потому что String[] instanceof Object[]это правда), вы можете использовать первое, чтобы быть более явным, если рецензенты кода продолжают спрашивать об этом.