【问题标题】:How to compare multiple enums using Reflection without know the enum type in Java?如何在不知道 Java 枚举类型的情况下使用反射比较多个枚举?
【发布时间】:2018-06-22 20:09:53
【问题描述】:

我的项目有多个枚举,有些类有多个枚举作为属性。 我需要创建一个日志,在编辑对象时显示以前的值和新值。我知道将普通字段作为字符串、整数等进行比较...但我不能使用枚举来做到这一点。

我是这样比较的,但不能使用枚举:

public static Map<Object, List<Object>> compareObjects(Object a, Object b){
 ...Some varibles declaration
  Field[] fieldsA a.getClass().getDeclaredFields();
  Field[] fieldsB b.getClass().getDeclaredFields();

int i = 0;
 for(; i < a.length; i++){
    ...some codintions
    if(fieldsA[i].get(a).equals(fieldsB[i].get(b)){

    ...

【问题讨论】:

  • 一个枚举文字没有它的声明类型就没有意义,它只是一个字符串。除非你知道它属于哪个enum 类型,否则你做不到。
  • 你能否展示你的类和你需要比较的代码?
  • 如果你知道它们的实际类型,你会如何比较这些枚举值?

标签: java reflection enums


【解决方案1】:

这是处理枚举的一种方法:

Object v1 = fields1[i].get(o1);
Object v2 = fields2[i].get(o2);
if (fields1[i].getType().isEnum()) {
    v1 = fields1[i].getType().getName() + '#' + v1;
}
if (fields2[i].getType().isEnum()) {
    v2 = fields2[i].getType().getName() + '#' + v2;
}

if (v1.equals(v2)) {
    System.out.println("Field #" + i + " matches");
}
else {
    System.out.println("Field #" + i + " changed from \"" + v1 + "\" to \"" + v2);
}

例如,给定这些枚举:

enum Color { Red, Green, Blue; }
enum RGB { Red, Green, Blue; }

Color.Red 字段与RGB.Red 字段进行比较会失败,因为实际比较的是“Color#Red”和“RGB#Red”。

也就是说,您可能面临更大的问题。 getDeclaredFields() 的文档说:

返回的数组中的元素没有排序,也没有任何特定的顺序。

因此,您可以比较两个等效对象,但如果 getDeclaredFields 以不同的顺序返回字段,您的测试将失败。至少,您需要按getName() 对字段进行排序,这样您就有了一致的顺序。另外,在比较值之前比较名称,这样您就知道您是在比较 x 和“x”,而不是 xy

【讨论】:

  • getEnumConstants 可用于按顺序获取 - 然后您可以使用 .name 进行比较。但是具有相同常量的枚举呢?但它们还有其他字段。就像RGB 枚举也会为每个枚举常量定义int value 字段。
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 2011-05-28
相关资源
最近更新 更多