将对象与原始类型进行比较

3

我希望对我的getClass().getField(...).set(...)进行安全检查,设置的值应该与该字段的类型匹配(例如int x = 1只允许设置整数)。问题是,我很难找到比较两者的方法。目前这是代码:

int foo = 14;

Field field = getClass().getDeclaredField("foo");
Object source = this;

// make the field accessible...

public void safeSet(Object newValue) throws IllegalAccessException {
    // compare the field.getType() to the newValue type
    field.set(source, newValue);
}

我尝试了很多方法,并在网上搜索了一段时间,但找不到一个仅关注此用法的答案。我尝试过像field.getType().getClass().equals(newValue.getClass())field.getType().equals(newValue)等方法,但都无法正常工作。在这种情况下,如何合理地比较原始的field.getType()和传入的对象值,或者如何比较intInteger

Java中确实缺少原始类型与其包装类之间的关联。需要注意的是,要么使用getClass().getField("..."),要么使用Xxx.class.getDeclaredField("...")来处理子类。 - Joop Eggen
如果(field.getType().isPrimitive() && field.get(source).getClass() != newValue.getClass()) /* error */。这是因为原始值永远不可能为null,因此总会有一个旧值,其包装表示必须与包装的新值具有相同的类型。当您不想读取字段时,请查看如何获取类型的默认值 - Holger
2个回答

3

您的朋友正在使用Class.isAssignableFrom()方法。

因为您想要给一个字段赋值,这是内置的解决方案。

if (getClass().getDeclaredField("foo").getType().isAssignableFrom(newValue.getClass())) {
    ....
}

它也适用于原始类型。

尝试使用我的值进行操作时,检查会返回 false 的断言。相同的值,对象是“2”,断言失败。 - Frontear

2

步骤1: 检查field.isPrimitive()。如果返回true,则它是一个原始类型,然后继续第3步。

步骤2: 如果不是原始类型,则可以直接检查field.getType() == newValue.getClass(),然后设置值。

步骤3: 如果是原始类型,则需要有一个静态映射表。

public final static Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
static {
    map.put(boolean.class, Boolean.class);
    map.put(byte.class, Byte.class);
    map.put(short.class, Short.class);
    map.put(char.class, Character.class);
    map.put(int.class, Integer.class);
    map.put(long.class, Long.class);
    map.put(float.class, Float.class);
    map.put(double.class, Double.class);
}

Class<?> clazz = map.get(field.getType());
then check clazz == newValue.getClass() and then set the variable.

1
很好的解决方案,但对于非原始类型,继承意味着要检查 field.getType().isAssignableFrom(value.getClass()) - Joop Eggen
在第二步中,如果分配的值是原始类型的子类型或声明的类型是接口,则==无法工作。请改用Class.isAssignableFrom,它是一种通用解决方案。 - gaborsch
@gaborsch 我同意你的观点,当需要包含子类时。对于严格的类检查,例如在这里,他只希望原始数据类型被更改。使用 == 将起作用。 - Sagar Gandhi
我希望这不是我必须采取的解决方案,但可悲的是,我找不到其他适用的通用方式。也许在未来Java可以实现一些有助于这个问题的东西? - Frontear

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接