55

我正在尝试确定对象上字段的类型。我不知道传递给我的对象的类型,但我需要找到longs 的字段。区分盒装的 s 很容易,Long但原语long似乎更难。

可以确保传递给我的对象只有Longs,而不是原语,但我宁愿没有。所以我所拥有的是:

for (Field f : o.getClass().getDeclaredFields()) {
    Class<?> clazz = f.getType();
    if (clazz.equals(Long.class)) {
        // found one -- I don't get here for primitive longs
    }
}

一种似乎可行的hacky方式是:

for (Field f : o.getClass().getDeclaredFields()) {
    Class<?> clazz = f.getType();
    if (clazz.equals(Long.class) ||  clazz.getName().equals("long")) {
        // found one
    }
}

如果有的话,我真的很想要一种更清洁的方法来做到这一点。如果没有更好的方法,那么我认为要求我收到的对象仅使用Long(not long) 将是一个更好的 API。

有任何想法吗?

4

4 回答 4

82

您使用错误的常量来检查 Long 原语 - use Long.TYPE,可以在包装器上使用类似命名的常量找到其他原始类型。例如:Byte.TYPECharacter.TYPE等。

于 2009-12-11T23:46:24.377 回答
68
o.getClass().getField("fieldName").getType().isPrimitive();
于 2009-12-12T04:30:34.670 回答
23

你可以使用

boolean.class
byte.class
char.class
short.class
int.class
long.class
float.class
double.class
void.class

如果您正在使用反射,您为什么要关心,为什么要进行此检查。get/set 方法始终使用对象,因此您不需要知道该字段是否为原始类型(除非您尝试将原始类型设置为 null 值。)

实际上,对于 get() 方法,您不需要知道它是哪种类型。你可以做

// any number type is fine.
Number n = field.get(object);
long l = n.longValue();

如果您不确定它是否是数字类型,您可以这样做

Object o = field.get(object); // will always be an Object or null.
if (o instanceof Number) {
     Number n = (Number) o;
     long l = n.longValue();
于 2009-12-12T15:29:47.513 回答
8
  • 检测long类型为 uselong.class或的字段Long.TYPE

  • 检测Long类型为 use的字段Long.class

例子:

for (Field f : o.getClass().getDeclaredFields()) {
    Class<?> clazz = f.getType();
    // to detect both Long and long types
    if (Long.class.equals(clazz) || long.class.equals(clazz)) {
        // found one
    }
}

注意事项

Long.TYPE是静态常量成员,等价于long.class.

代码片段表单Long

/**
 * The {@link Class} object that represents the primitive type {@code long}.
 */
@SuppressWarnings("unchecked")
public static final Class<Long> TYPE
        = (Class<Long>) long[].class.getComponentType();

还要检查Integer.class 和 Integer.TYPE问题之间的差异的答案

于 2016-09-07T17:18:29.940 回答