Чи є різниця в налаштуваннях або поведінці між використанням:
if(obj.getClass().isArray()) {}
і
if(obj instanceof Object[]) {}
?
Чи є різниця в налаштуваннях або поведінці між використанням:
if(obj.getClass().isArray()) {}
і
if(obj instanceof Object[]) {}
?
Відповіді:
У більшості випадків вам слід скористатися instanceofоператором, щоб перевірити, чи є об’єкт масивом.
Як правило, ви перевіряєте тип об'єкта перед тим, як спустити на конкретний тип, який відомий під час компіляції. Наприклад, можливо, ви написали якийсь код, який може працювати з a Integer[]чи an 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є type int[]say, то це буде масив, 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, тож ти (або Гроовий ??) повинен був зробити щось не так, якби припустити, що кожен Typeє Class.
Відбиття масиву Java - це для випадків, коли у вас немає екземпляра класу для "instanceof". Наприклад, якщо ви пишете якусь рамку ін'єкції, яка вводить значення в новий примірник класу, як, наприклад, JPA, вам потрібно використовувати функцію isArray ().
Я про це блогував раніше у грудні. http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Якщо у вас колись є вибір між рефлексивним рішенням і невідбиваючим рішенням, ніколи не вибирайте світловідбиваюче (за участю об'єктів класу). Справа не в тому, що це "Неправильно" чи що-небудь, але все, що включає рефлексію, як правило, менш очевидно і менш зрозуміло.
Немає різниці в поведінці, яку я можу знайти між ними (крім очевидного нульового випадку). Щодо того, яку версію віддати перевагу, я б пішов з другою. Це стандартний спосіб зробити це на Java.
Якщо це бентежить читачів вашого коду (тому що String[] instanceof Object[]це правда), ви можете скористатися першим, щоб бути більш чітким, якщо рецензенти коду продовжують запитувати про це.