【问题标题】:Compare an Object to a primitive type将 Object 与原始类型进行比较
【发布时间】:2019-05-28 20:58:01
【问题描述】:

我想对我的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() 与传入的 Object 值进行比较,或者,在这种情况下,我将如何将 intInteger 进行比较?

【问题讨论】:

  • Java 中确实缺少原始类型与其包装类的关联。一句话:getClass().getField("...")Xxx.class.getDeclaredField("...") 处理子类。
  • if(field.getType().isPrimitive() && field.get(source).getClass() != newValue.getClass()) /* error */。因为原始值永远不可能是null,所以工作,因此,总是有一个旧值,其包装表示必须与包装的新值具有相同的类型。当您不想阅读该字段时,请查看how to get the default value for a type...

标签: java reflection types primitive


【解决方案1】:

你的朋友是Class.isAssignableFrom()

因为您想为字段分配值,所以这是执行此操作的内置解决方案。

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

它也适用于原始类型。

【讨论】:

  • 使用我的值尝试此操作会导致检查的断言为 false。相同的值,对象为 '2',断言失败
【解决方案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.

【讨论】:

  • 很好的解决方案,但对于非原始类型继承意味着检查field.getType().isAssignableFrom(value.getClass())
  • 在第 2 步中,如果分配的值是原始值的子类型,或者声明的类型是接口,== 将不起作用。改用Class.isAssignableFrom,这是一个通用的解决方案。
  • @gaborsch 当您需要包含子类时,我同意您的看法。对于严格的类检查,例如在这里,他只想更改原始数据类型。 == 会起作用。
  • 我希望这不是我必须采用的解决方案,但遗憾的是,我找不到另一种通用的方法。也许将来 Java 可以实现一些对此有所帮助的东西?
猜你喜欢
  • 2023-03-22
  • 1970-01-01
  • 2019-06-24
  • 2017-12-02
  • 2016-10-02
  • 2015-01-31
  • 1970-01-01
  • 2012-04-29
  • 2021-06-27
相关资源
最近更新 更多