2016-06-06 34 views
0

Ich habe die Methode, die Field und ObjectWie zu verstehen, dass Feld Nummer ist?

public String format(Field field, Object o) {....} 

ich gegossen werden kann, um Nummer will wissen, ob Feld akzeptiert.

Ich habe bemerkt, dass, wenn so etwas schreiben (für lange primitive):

field.getType().isAssignableFrom(long.class) 

kehrt true

aber

field.getType().isAssignableFrom(Long.class) 

kehrt false

und

field.getType().isAssignableFrom(Number.class) 

kehrt false zu


Auch

field.getType().cast(Number.class) 

kehrt ClassCastException

Bitte helfen Methode zu schreiben, die true wenn Feld tatsächlich Nummer zurück (int, long, byte ..., auch alle Wrapper) und false in anderen Fällen.

Gibt es einfachere Weise als:

public String format(Field field, Object o) { 
    field.setAccessible(true); 
    Object value = null; 
    try { 
     value = field.get(o); 
     if (value instanceof Number) { 
      return field.get(o).toString(); 
     } 
    } catch (IllegalAccessException e) { 
     .... 
    } 
    ... 
} 

?

+0

versuchen, wenn (Anzahl. class.isAssignableFrom (field.getType())). Und lesen Sie die Java-Dokumentation für weitere Details zu dieser Methode. – zombie

+0

@zombie diese Antwort existiert bereits und es ist falsch – gstackoverflow

Antwort

-2

Verwenden instanceof zu überprüfen, ob ein gegossenes möglich ist:

if(field.getType() instanceof Number) 
    field.getType().cast(Number.class); 
+0

aus meiner Sicht lang, um Nummer sollte gegossen werden – gstackoverflow

+0

gibt false zurück, wenn Feld lang – gstackoverflow

2

Es gibt einen Unterschied zwischen dem, was IsAssignableFrom (Typ) gibt Ihnen und welche Reflexion gibt Ihnen: IsAssignableFrom prüft Kompatibilität direkte Typzuweisung, während Reflexion implizit führt Boxing/Unboxing für Primitive durch. Sie müssen diesen Unterschied explizit berücksichtigen. Eine Möglichkeit, dies zu tun, ist die kompatibele Primitiven in einem Set zu repräsentieren und jede Art zu akzeptieren, dass der Satz sowie Nummernvergabe kompatible Typen umfasst:

private final static Set<Class<?>> NUMBER_REFLECTED_PRIMITIVES; 
static { 
    Set<Class<?>> s = new HashSet<>(); 
    s.add(byte.class); 
    s.add(short.class); 
    s.add(int.class); 
    s.add(long.class); 
    s.add(float.class); 
    s.add(double.class); 
    NUMBER_REFLECTED_PRIMITIVES = s; 
} 

public static boolean isReflectedAsNumber(Class<?> type) { 
    return Number.class.isAssignableFrom(type) || NUMBER_REFLECTED_PRIMITIVES.contains(type); 
} 

vorsichtig sein, aber, dass Sie unerwartete Typen auftreten können, die Bedingung zu erfüllen, z.B BigDecimal, AtomicLong usw. sind Subtypen von Number.

2

Sie suchen wahrscheinlich so etwas wie:

private static final Set<Class<?>> primitiveNumbers = Stream 
     .of(int.class, long.class, float.class, 
      double.class, byte.class, short.class) 
     .collect(Collectors.toSet()); 

private static boolean isNumericType(Class<?> cls) { 
    if (cls.isPrimitive()) { 
     return primitiveNumbers.contains(cls); 
    } else { 
     return Number.class.isAssignableFrom(cls); 
    } 
} 

Sie können eine andere Dienstprogramm Methode hinzufügen Filed wie zu handhaben:

private static boolean holdsNumericType(Field f) { 
    return isNumericType(f.getType()); 
} 

Demo:

System.out.println(isNumericType(int.class));  //true 
System.out.println(isNumericType(Integer.class)); //true 
System.out.println(isNumericType(byte.class));  //true 
System.out.println(isNumericType(Byte.class));  //true 
System.out.println(isNumericType(Character.class)); //false 
System.out.println(isNumericType(Boolean.class)); //false