Bestimmen, ob ein Objekt vom primitiven Typ ist

Ich habe ein Array Object[] , und ich versuche, diejenigen zu finden, die Primitive sind. Ich habe versucht, 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?

Solutions Collecting From Web of "Bestimmen, ob ein Objekt vom primitiven Typ ist"

Die Typen in einem Object[] werden niemals wirklich primitiv sein – weil Sie Referenzen haben! Hier ist der Typ von i int während der Typ des Objekts, auf das mit o verwiesen wird, Integer (aufgrund des automatischen Boxens).

Es klingt wie Sie müssen herausfinden, ob der Typ “Wrapper für primitive” ist. Ich glaube nicht, dass da etwas in die Standardbibliotheken eingebaut ist, aber es ist einfach zu programmieren:

 import java.util.*; public class Test { public static void main(String[] args) { System.out.println(isWrapperType(String.class)); System.out.println(isWrapperType(Integer.class)); } private static final Set> WRAPPER_TYPES = getWrapperTypes(); public static boolean isWrapperType(Class< ?> clazz) { return WRAPPER_TYPES.contains(clazz); } private static Set> getWrapperTypes() { Set> ret = new HashSet>(); ret.add(Boolean.class); ret.add(Character.class); ret.add(Byte.class); ret.add(Short.class); ret.add(Integer.class); ret.add(Long.class); ret.add(Float.class); ret.add(Double.class); ret.add(Void.class); return ret; } } 

commons-lang ClassUtils hat relevante Methoden . Die neue Version hat:

 boolean isPrimitiveOrWrapped = ClassUtils.isPrimitiveOrWrapper(object.getClass()); 

Die alten Versionen haben die Methode wrapperToPrimitive(clazz) , die die primitive Korrespondenz wrapperToPrimitive(clazz) . So können Sie tun:

 boolean isPrimitiveOrWrapped = clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null; 

Googles Guava-Bibliothek enthält ein Primitives-Dienstprogramm, das prüft, ob eine class ein Wrapper-Typ für ein Primitiv ist: http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/primitives/Primitives.html

 Primitives.isWrapperType(class) 

Class.isPrimitive () funktioniert für Primitive

Für diejenigen, die knappe Codes mögen.

 private static final Set WRAPPER_TYPES = new HashSet(Arrays.asList( Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class)); public static boolean isWrapperType(Class clazz) { return WRAPPER_TYPES.contains(clazz); } 

Ab Java 1.5 gibt es ein neues Feature namens Auto-Boxing. Der Compiler macht das selbst. Wenn eine Opportunity erkannt wird, konvertiert sie einen primitiven Typ in die entsprechende Wrapperklasse.

Was hier wahrscheinlich passiert ist, wenn du es erklärst

 Object o = i; 

Der Compiler kompiliert diese Aussage als Sprichwort

 Object o = Integer.valueOf(i); 

Dies ist automatisches Boxen. Dies würde die Ausgabe erklären, die Sie erhalten. Diese Seite aus der Java 1.5-Spezifikation erläutert Auto-Boxen genauer.

Integer ist kein Primitiv, Class.isPrimitive() lügt nicht.

Ich denke, das passiert durch Auto-Boxen .

 int i = 3; Object o = i; o.getClass().getName(); // prints Integer 

Sie können eine Hilfsmethode implementieren, die diesen bestimmten Boxklassen entspricht und Ihnen angibt, ob eine bestimmte class primitiv ist.

 public static boolean isWrapperType(Class< ?> clazz) { return clazz.equals(Boolean.class) || clazz.equals(Integer.class) || clazz.equals(Character.class) || clazz.equals(Byte.class) || clazz.equals(Short.class) || clazz.equals(Double.class) || clazz.equals(Long.class) || clazz.equals(Float.class); } 

Sie müssen sich mit dem automatischen Boxen von Java beschäftigen.
Lass uns den Code nehmen

  Öffentlicher classntest
 {
     public static void main (Zeichenfolge [] args)
     {
         int i = 3;
         Objekt o = i;
         Rückkehr;
     }
 } 

Sie erhalten die classn test.class und javap -c test. Sehen Sie sich den generierten Bytecode an.

  Zusammengestellt aus "test.java"
 öffentlicher classntest erweitert java.lang.Object {
 öffentlicher Test ();
   Code:
    0: aload_0
    1: ruft Spezial # 1 auf;  // Methode java / lang / Objekt. "" :() V
    4: Rückkehr 

public static void main (java.lang.String []);
Code:
0: iconst_3
1: istore_1
2: iload_1
3: invokestatic # 2; // Methode java / lang / Integer.valueOf: (I) Ljava / lang / Integer;
6: astore_2
7: Rückkehr

} Wie Sie sehen können, wurde der Java-Compiler hinzugefügt

  invokestatic # 2;  // Methode java / lang / Integer.valueOf: (I) Ljava / lang / Integer; 

um eine neue Ganzzahl aus Ihrem int zu erzeugen und speichert dann dieses neue Objekt in o über astore_2

 public static boolean isValidType(Class< ?> retType) { if (retType.isPrimitive() && retType != void.class) return true; if (Number.class.isAssignableFrom(retType)) return true; if (AbstractCode.class.isAssignableFrom(retType)) return true; if (Boolean.class == retType) return true; if (Character.class == retType) return true; if (String.class == retType) return true; if (Date.class.isAssignableFrom(retType)) return true; if (byte[].class.isAssignableFrom(retType)) return true; if (Enum.class.isAssignableFrom(retType)) return true; return false; } 

Nur so können Sie sehen, dass es möglich ist, dass isPrimitive True zurückgibt (da Sie genügend Antworten haben, die Ihnen zeigen, warum es falsch ist):

 public class Main { public static void main(final String[] argv) { final Class clazz; clazz = int.class; System.out.println(clazz.isPrimitive()); } } 

Dies ist wichtig, wenn eine Methode “int” statt “Integer” einnimmt.

Dieser Code funktioniert:

 import java.lang.reflect.Method; public class Main { public static void main(final String[] argv) throws Exception { final Method method; method = Main.class.getDeclaredMethod("foo", int.class); } public static void foo(final int x) { } } 

Dieser Code schlägt fehl (die Methode kann nicht gefunden werden):

 import java.lang.reflect.Method; public class Main { public static void main(final String[] argv) throws Exception { final Method method; method = Main.class.getDeclaredMethod("foo", Integer.class); } public static void foo(final int x) { } } 

Wie einige Leute bereits gesagt haben, ist dies auf Autoboxing zurückzuführen .

Sie könnten eine Hilfsmethode erstellen, um zu überprüfen, ob die class des Objekts Integer , Double usw. ist. Es gibt jedoch keine Möglichkeit zu wissen, ob ein Objekt durch Autoboxieren eines Primitivs erstellt wurde . Sobald es eingerahmt ist, sieht es wie ein explizit erstelltes Objekt aus.

Wenn Sie also nicht sicher sind, dass Ihr Array niemals eine Wrapper-class ohne Autoboxing enthalten wird, gibt es keine echte Lösung.

Die primären Wrapper-Typen reagieren nicht auf diesen Wert. Dies ist für die classnrepräsentation von Primitiven, obwohl ich abgesehen von der Reflektion nicht an zu viele Verwendungen dafür denken kann. Also zum Beispiel

 System.out.println(Integer.class.isPrimitive()); 

druckt “falsch”, aber

 public static void main (String args[]) throws Exception { Method m = Junk.class.getMethod( "a",null); System.out.println( m.getReturnType().isPrimitive()); } public static int a() { return 1; } 

druckt “wahr”

Ich komme zu spät zur Show, aber wenn Sie ein Feld testen, können Sie getGenericType :

 import static org.junit.Assert.*; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import org.junit.Test; public class PrimitiveVsObjectTest { private static final Collection PRIMITIVE_TYPES = new HashSet<>(Arrays.asList("byte", "short", "int", "long", "float", "double", "boolean", "char")); private static boolean isPrimitive(Type type) { return PRIMITIVE_TYPES.contains(type.getTypeName()); } public int i1 = 34; public Integer i2 = 34; @Test public void primitive_type() throws NoSuchFieldException, SecurityException { Field i1Field = PrimitiveVsObjectTest.class.getField("i1"); Type genericType1 = i1Field.getGenericType(); assertEquals("int", genericType1.getTypeName()); assertNotEquals("java.lang.Integer", genericType1.getTypeName()); assertTrue(isPrimitive(genericType1)); } @Test public void object_type() throws NoSuchFieldException, SecurityException { Field i2Field = PrimitiveVsObjectTest.class.getField("i2"); Type genericType2 = i2Field.getGenericType(); assertEquals("java.lang.Integer", genericType2.getTypeName()); assertNotEquals("int", genericType2.getTypeName()); assertFalse(isPrimitive(genericType2)); } } 

Die Oracle-Dokumente listen die 8 primitiven Typen auf.

Das ist der einfachste Weg, an den ich denken könnte. Die Wrapper-classn sind nur im java.lang Paket vorhanden. Und abgesehen von den Wrapper-classn hat keine andere class in java.lang das Feld TYPE . Sie könnten das verwenden, um zu überprüfen, ob eine class die Wrapper-class ist oder nicht.

 public static boolean isBoxingClass(Class< ?> clazz) { String pack = clazz.getPackage().getName(); if(!"java.lang".equals(pack)) return false; try { clazz.getField("TYPE"); } catch (NoSuchFieldException e) { return false; } return true; } 

Erhalten Sie einen Überblick über BeanUtils von Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/

Wahrscheinlich hat die Apache-Variante (Commons Beans) ähnliche functionen.

Sie können bestimmen, ob ein Objekt Wrapper-Typ ist, durch folgende statementen:

 ***objClass.isAssignableFrom(Number.class);*** 

Außerdem können Sie ein primitives Objekt mithilfe der isPrimitive () -Methode ermitteln

 public class CheckPrimitve { public static void main(String[] args) { int i = 3; Object o = i; System.out.println(o.getClass().getSimpleName().equals("Integer")); Field[] fields = o.getClass().getFields(); for(Field field:fields) { System.out.println(field.getType()); } } } Output: true int int class java.lang.Class int