Ich habe ein Object[]
Array und versuche, diejenigen zu finden, die primitiv sind. Ich habe versucht zu verwenden Class.isPrimitive()
, aber es scheint, dass ich etwas falsch mache:
int i = 3;
Object o = i;
System.out.println(o.getClass().getName() + ", " +
o.getClass().isPrimitive());
druckt java.lang.Integer, false
.
Gibt es einen richtigen Weg oder eine Alternative?
java
reflection
Bohrer3r
quelle
quelle
int.class.isPrimitive()
Erträgetrue
;Integer.class.isPrimitive()
ergibtfalse
.Antworten:
Die Typen in einem
Object[]
werden niemals wirklich primitiv sein - weil Sie Referenzen haben! Hier ist die Art deri
ist ,int
während die Art des Objekts referenziert durcho
istInteger
(aufgrund der Auto-Box).Es hört sich so an, als müssten Sie herausfinden, ob der Typ ein "Wrapper für Primitive" ist. Ich glaube nicht, dass etwas in die Standardbibliotheken eingebaut ist, aber es ist einfach zu codieren:
quelle
java.lang.<type>.TYPE
, was natürlich das Primitiv selbst ist. Es scheint, dass ich es nicht vermeiden kann, jeden Typ einzeln zu prüfen, danke für die nette Lösung.HashSet
ermöglicht den Zugriff in O (1), während eine Reihe vonif
Anweisungen oderswitch
Anweisungen im schlimmsten Fall O (Anzahl der Wrapper) erfordert. In der Praxis ist es fraglich, obif
Anweisungen für die feste Anzahl von 9 Wrappern vielleicht doch nicht schneller sind als Hash-basierter Zugriff.commons-lang
ClassUtils
hat relevante Methoden .Die neue Version hat:
Die alten Versionen haben eine
wrapperToPrimitive(clazz)
Methode, die die primitive Entsprechung zurückgibt .quelle
Die Guava-Bibliothek von Google verfügt über ein Dienstprogramm für Grundelemente , mit dem überprüft wird, ob eine Klasse ein Wrapper-Typ für ein Grundelement ist :
Primitives.isWrapperType(class)
.Class.isPrimitive () funktioniert für Grundelemente
quelle
Für diejenigen, die knappen Code mögen.
quelle
void.class.isPrimitive()
gibt true zurückVoid
istnull
;) Es ist nützlich,Callable<Void>
um ein Callable zu erstellen, das nichts zurückgibt.Ab Java 1.5 gibt es eine neue Funktion namens Auto-Boxing. Der Compiler macht das selbst. Wenn es eine Opportunity sieht, konvertiert es einen primitiven Typ in seine entsprechende Wrapper-Klasse.
Was hier wahrscheinlich passiert, ist, wenn Sie erklären
Der Compiler kompiliert diese Anweisung wie folgt
Dies ist Auto-Boxing. Dies würde die Ausgabe erklären, die Sie erhalten. Diese Seite aus der Java 1.5-Spezifikation erklärt das Auto-Boxen ausführlicher.
quelle
Integer.valueOf(int)
selbst gibt nur dann einen zwischengespeicherten Wert zurück, wenn das Argument "ein Byte" ist (lesen Sie: zwischen -128, 127, beide einschließlich). Sonst ruft es annew Integer(int)
. Siehe: developer.classpath.org/doc/java/lang/… , hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…Integer
ist kein Primitiv,Class.isPrimitive()
lügt nicht.quelle
Ich denke, das passiert durch Auto-Boxen .
Sie können eine Dienstprogrammmethode implementieren, die diesen bestimmten Boxklassen entspricht und Ihnen angibt, ob eine bestimmte Klasse primitiv ist.
quelle
.equals
zu==
. Klassen sind Singletons.Sie müssen sich mit dem Auto-Boxen von Java befassen.
Sie erhalten die Klassen test.class und javap -c test , mit denen Sie den generierten Bytecode überprüfen können. Wie Sie sehen können, wurde der Java-Compiler hinzugefügt um eine neue Ganzzahl aus Ihrem int zu erstellen und dieses neue Objekt dann über astore_2 in o zu speichernNehmen wir den Code
quelle
quelle
Nur damit Sie sehen können, dass isPrimitive möglicherweise true zurückgibt (da Sie genügend Antworten haben, die Ihnen zeigen, warum es falsch ist):
Dies ist in der Reflexion wichtig, wenn eine Methode "int" anstelle einer "Ganzzahl" aufnimmt.
Dieser Code funktioniert:
Dieser Code schlägt fehl (die Methode kann nicht gefunden werden):
quelle
Wie bereits mehrere Leute gesagt haben, ist dies auf Autoboxing zurückzuführen .
Sie könnten eine Dienstprogramm Methode zu erstellen , ob die Klasse des Objekts zu überprüfen ist
Integer
,Double
etc. Aber es gibt keine Möglichkeit zu wissen , ob ein Objekt von Autoboxing einen primitiven erstellt wurde ; Sobald es eingerahmt ist, sieht es aus wie ein explizit erstelltes Objekt.Wenn Sie also nicht sicher sind, dass Ihr Array ohne Autoboxing niemals eine Wrapper-Klasse enthält, gibt es keine echte Lösung.
quelle
Die primitiven Wrapper-Typen reagieren nicht auf diesen Wert. Dies ist für die Klassendarstellung von Primitiven gedacht, obwohl ich mir, abgesehen von der Reflexion, nicht allzu viele Verwendungszwecke vorstellen kann. So zum Beispiel
druckt "false", aber
druckt "wahr"
quelle
Ich bin zu spät zur Show, aber wenn Sie ein Feld testen, können Sie Folgendes verwenden
getGenericType
:In den Oracle-Dokumenten sind die 8 primitiven Typen aufgeführt.
quelle
Dies ist der einfachste Weg, den ich mir vorstellen kann. Die Wrapper-Klassen sind nur im
java.lang
Paket vorhanden. Abgesehen von den Wrapper-Klassen hat keine andere Klasse injava.lang
ein Feld mit dem NamenTYPE
. Sie können damit überprüfen, ob eine Klasse eine Wrapper-Klasse ist oder nicht.quelle
Holen Sie sich BeanUtils von Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/
Wahrscheinlich hat die Apache-Variante (Commons Beans) eine ähnliche Funktionalität.
quelle
Sie können anhand der folgenden Anweisungen feststellen, ob ein Objekt vom Typ Wrapper ist:
Sie können auch ein primitives Objekt mithilfe der isPrimitive () -Methode bestimmen
quelle
quelle
Für Benutzer von Javapoet gibt es auch folgende Möglichkeiten:
quelle