Odbicie tablicy Java: isArray vs. instanceof

Czy istnieje różnica w preferencjach lub zachowaniu pomiędzy używaniem:

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

I

if(obj instanceof Object[]) {}

?

Author: David Citron, 2008-10-21

8 answers

W większości przypadków należy użyć operatora instanceof do sprawdzenia, czy obiekt jest tablicą.

Ogólnie rzecz biorąc, testujesz typ obiektu przed przejściem do określonego typu, który jest znany w czasie kompilacji. Na przykład, być może napisałeś kod, który może działać z Integer[] lub int[]. Chcesz pilnować swoich rzutów 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 ...
Na poziomie JVM operator instanceof tłumaczy się na określony "instanceof" kod bajtowy, który jest zoptymalizowany w większości JVM wdrożenia.

W rzadszych przypadkach możesz użyć odbicia do przemierzania wykresu obiektów nieznanych typów. W takich przypadkach metoda isArray() może być pomocna, ponieważ nie znasz typu komponentu podczas kompilacji; możesz na przykład implementować jakiś mechanizm serializacji i być w stanie przekazać każdy komponent tablicy do tej samej metody serializacji, niezależnie od typu.

Istnieją dwa szczególne przypadki: odniesienia null i odniesienia do primitive tablice.

Odniesienie null spowoduje instanceof wynik false, podczas gdy isArray rzuca NullPointerException.

Zastosowany do prymitywnej tablicy, instanceof daje false, chyba że typ komponentu po prawej stronie jest dokładnie zgodny z typem komponentu. Natomiast isArray() zwróci true dla dowolnego typu komponentu.

 191
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 00:37:04

W tym drugim przypadku, jeśli obj jest null, to nie otrzymasz NullPointerException, ale false.

 31
Author: Burkhard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-27 15:28:00

Jeśli obj jest typu int[] powiedzmy, to będzie miała tablicę Class, ale nie będzie instancją Object[]. Więc co chcesz zrobić z obj. Jeśli zamierzasz go rzucić, wybierz instanceof. Jeśli zamierzasz użyć reflection, użyj .getClass().isArray().

 8
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 12:16:05

Ostatnio napotkałem problem z aktualizacją aplikacji Groovy z JDK 5 do JDK 6. Użycie isArray() nie powiodło się w JDK6:

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

Zmiana na instanceof Object[] naprawiła to.

 5
Author: dturanski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-13 13:44:14

getClass().isArray() jest znacznie wolniejszy w Sun Java 5 lub 6 JRE niż w IBM.

Tak bardzo, że używanie {[1] } jest szybsze Na Sun JVM.

 4
Author: Sebastien Tardif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 19:15:20

Java array reflection jest dla przypadków, w których nie masz instancji klasy dostępnej do wykonania "instanceof". Na przykład, jeśli piszesz jakiś framework injection, który wstrzykuje wartości do nowej instancji klasy, tak jak robi to JPA, musisz użyć funkcji isArray ().

Pisałem o tym wcześniej w grudniu. http://blog.adamsbros.org/2010/12/08/java-array-reflection/

 3
Author: Trenton D. Adams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-01 01:46:26

Jeśli kiedykolwiek masz wybór między rozwiązaniem odblaskowym a rozwiązaniem nie odblaskowym, nigdy nie wybieraj rozwiązania odblaskowego (obejmującego obiekty klasowe). Nie chodzi o to, że jest to "złe" czy coś, ale wszystko, co wiąże się z refleksją, jest generalnie mniej oczywiste i mniej jasne.

 2
Author: Bill K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-20 21:06:06

Nie ma różnicy w zachowaniu, które mogę znaleźć między tymi dwoma (poza oczywistym przypadkiem zerowym). Jeśli chodzi o to, którą wersję preferować, wybrałbym drugą. Jest to standardowy sposób na to w Javie.

Jeśli to myli czytelników Twojego kodu (ponieważ String[] instanceof Object[] jest prawdą), możesz użyć pierwszego, aby być bardziej wyraźnym, jeśli recenzenci wciąż o to pytają.

 0
Author: hazzen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-20 21:02:27