Mam Object[]
tablicę i próbuję znaleźć te, które są prymitywami. Próbowałem użyć Class.isPrimitive()
, ale wygląda na to, że robię coś źle:
int i = 3;
Object o = i;
System.out.println(o.getClass().getName() + ", " +
o.getClass().isPrimitive());
wydruki java.lang.Integer, false
.
Czy jest właściwy sposób lub alternatywa?
java
reflection
drill3r
źródło
źródło
int.class.isPrimitive()
plonytrue
;Integer.class.isPrimitive()
plonyfalse
.Odpowiedzi:
Typy w an
Object[]
nigdy nie będą naprawdę prymitywne - ponieważ masz odniesienia! Tutaj typi
jest,int
podczas gdy typ obiektu, do którego się odwołuje,o
jestInteger
(ze względu na automatyczne boksowanie).Wygląda na to, że musisz dowiedzieć się, czy typ jest „opakowaniem dla prymitywów”. Nie sądzę, aby w standardowych bibliotekach było coś wbudowanego, ale łatwo to zakodować:
źródło
java.lang.<type>.TYPE
samego prymitywu. Wygląda na to, że nie uda mi się uniknąć sprawdzania każdego typu osobno, dzięki za fajne rozwiązanie.HashSet
pozwala na dostęp w O (1), podczas gdy wierszif
instrukcji lubswitch
instrukcji wymaga O (liczba opakowań) w najgorszym przypadku. W praktyce wątpliwe jest, czyif
instrukcje dla ustalonej liczby 9 opakowań nie są być może w końcu szybsze niż dostęp oparty na skrócie.commons-lang
ClassUtils
ma odpowiednie metody .Nowa wersja posiada:
Stare wersje mają
wrapperToPrimitive(clazz)
metodę, która zwraca pierwotną zgodność.źródło
Biblioteka Guava Google posiada narzędzie Primitives , że należy sprawdzić, czy klasa jest rodzajem wrapper dla prymitywne:
Primitives.isWrapperType(class)
.Class.isPrimitive () działa dla prymitywów
źródło
Dla tych, którzy lubią zwięzły kod.
źródło
void.class.isPrimitive()
zwraca trueVoid
jestnull
;) jest to przydatne do tworzenia elementu wywoływanego,Callable<Void>
który nic nie zwraca.Począwszy od Java 1.5 i nowszych, dostępna jest nowa funkcja o nazwie auto-boxing. Kompilator robi to sam. Kiedy widzi okazję, konwertuje typ pierwotny na odpowiednią klasę opakowania.
To, co prawdopodobnie dzieje się tutaj, to deklaracja
Kompilator skompiluje tę instrukcję, jak mówi
To jest auto-boks. To wyjaśniałoby otrzymane dane wyjściowe. Ta strona ze specyfikacją Java 1.5 bardziej szczegółowo wyjaśnia automatyczne boksowanie.
źródło
Integer.valueOf(int)
samo zwraca wartość zapisaną w pamięci podręcznej tylko wtedy, gdy argumentem jest „bajt” (czytaj: od -128 do 127 włącznie). W przeciwnym razie dzwoninew Integer(int)
. Zobacz: developer.classpath.org/doc/java/lang/... , hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/...Integer
nie jest prymitywem,Class.isPrimitive()
nie kłamie.źródło
Myślę, że dzieje się tak z powodu auto-boksu .
Możesz zaimplementować metodę narzędziową, która pasuje do tych konkretnych klas boksu i podaje, czy dana klasa jest prymitywna.
źródło
.equals
na==
. Klasy są singletonami.Musisz poradzić sobie z automatycznym boksowaniem java.
Otrzymasz klasę test.class i javap -c test, które pozwolą Ci sprawdzić wygenerowany kod bajtowy. Jak widać dodano kompilator java aby utworzyć nową liczbę całkowitą z int, a następnie przechowuje ten nowy obiekt w o za pośrednictwem astore_2Weźmy kod
źródło
źródło
Abyś mógł zobaczyć, że isPrimitive może zwrócić wartość true (ponieważ masz wystarczająco dużo odpowiedzi, które pokazują, dlaczego jest fałszywe):
Ma to znaczenie w refleksji, gdy metoda przyjmuje „int” zamiast „Integer”.
Ten kod działa:
Ten kod nie działa (nie można znaleźć metody):
źródło
Jak już kilka osób powiedziało, jest to spowodowane autoboxingiem .
Państwo mogłoby stworzyć metodę użytkową, by sprawdzić, czy klasa obiektu jest
Integer
,Double
itd Ale nie ma sposobu, aby wiedzieć, czy obiekt został stworzony przez autoboxing prymitywne ; po zapakowaniu wygląda jak obiekt utworzony jawnie.Więc jeśli nie wiesz na pewno, że twoja tablica nigdy nie będzie zawierała klasy opakowującej bez autoboxingu, nie ma prawdziwego rozwiązania.
źródło
Podstawowe typy opakowań nie będą reagować na tę wartość. To jest dla klasowej reprezentacji prymitywów, chociaż poza refleksją nie mogę wymyślić zbyt wielu zastosowań tego odręcznego. Na przykład
wypisuje „false”, ale
drukuje „prawda”
źródło
Spóźniłem się na pokaz, ale jeśli testujesz pole, możesz użyć
getGenericType
:Dokumentacja Oracle zawiera listę 8 typów pierwotnych.
źródło
To najprostszy sposób, jaki mogłem wymyślić. Klasy opakowania są obecne tylko w
java.lang
pakiecie. Poza klasami opakowującymi żadna inna klasajava.lang
nie ma pola o nazwieTYPE
. Możesz użyć tego do sprawdzenia, czy klasa jest klasą Wrapper, czy nie.źródło
Zdobądź BeanUtils ze Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/
Prawdopodobnie odmiana Apache (commons beans) ma podobną funkcjonalność.
źródło
możesz określić, czy obiekt jest typu opakowującego, korzystając z poniższych instrukcji:
a także można określić prymitywny obiekt za pomocą metody isPrimitive ()
źródło
źródło
Dla użytkowników javapoet jest też ten sposób:
źródło