我有接受Field
和Object
public String format(Field field, Object o) {....}
我想知道字段是否可以转换为数字。
我注意到如果写这样的东西(对于长原语):
field.getType().isAssignableFrom(long.class)
返回true
,但
field.getType().isAssignableFrom(Long.class)
返回false
和
field.getType().isAssignableFrom(Number.class)
也会返回false
另外
field.getType().cast(Number.class)
返回ClassCastException
请帮助编写方法,如果字段实际为数字true
,int
,long
...,还包括所有包装器,则byte
和{{} 1}}在其他情况下。
是否有比以下更简单的方法:
false
答案 0 :(得分:3)
isAssignableFrom(type)给出的内容与反射给出的内容之间存在差异:isAssignableFrom检查直接类型赋值兼容性,而reflect则隐式执行基元的装箱/取消装箱。您必须明确说明这一差异。一种方法是在Set中表示兼容的原语并接受该set包含的任何类型以及Number assignment兼容类型:
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);
}
请注意,您可能会遇到满足条件的意外类型,例如: BigDecimal,AtomicLong等是数字的子类型。
答案 1 :(得分:2)
你可能正在寻找类似的东西:
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);
}
}
您可以添加另一个实用工具方法来处理Filed
,例如:
private static boolean holdsNumericType(Field f) {
return isNumericType(f.getType());
}
演示:
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
答案 2 :(得分:-2)
使用instanceof
检查演员是否可行:
if(field.getType() instanceof Number)
field.getType().cast(Number.class);