【问题标题】:How to check equality of annotations?如何检查注释的相等性?
【发布时间】:2011-07-26 06:12:52
【问题描述】:

你会如何实现这个方法:

public boolean equal(Annotation a1, Annotation a2) {
   ...
}

示例输入():

@First(name="1", value="1"), @Second(name="1", value="1")
@First(value="2"),           @First(name="2")
@First(value="3"),           @First(value="3")
@Second(name="4", value="4), @Second(name="4", value="4")

样本输出:

false
false
true
true

如您所见,equal 的预期行为很明确,并且类似于 java 中常规对象的标准 equals 方法的预期行为(问题是我们无法覆盖 equals 的注释)。

是否有任何库或标准实现?

【问题讨论】:

  • a1.equals(a2); 可以。这是注解的默认行为——它检查注解的类型是否相同以及每个注解字段是否相等。不需要特殊的解决方法。

标签: java annotations equals


【解决方案1】:

overriden equalsAnnotation 不起作用吗?也许我不明白你的问题。

【讨论】:

  • 能否请您告诉我如何在注释类上覆盖equals(让我们以@Sample 注释作为起点;equals 正文并不重要,只显示您将在哪里写下来)。谢谢。
  • 注解已经在 J​​ava 中了。默认设置不适合你吗?你看过我提供的链接吗?可能有什么误会……
  • 也许你是对的,我会调查它(它是如何工作的并不明显,因为实际的 equals 实现在其他地方但不在 Annotation 类中)。
【解决方案2】:

如果要检查a1和a2是否是同一个注解。试试这个: a1.annotationType().equals(a2.annotationType())

【讨论】:

    【解决方案3】:

    我的答案令人讨厌的部分是我无法扩展自定义注释(在继承的意义上)。那将简化 equals 方法。

    First.java

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface First  {
      String name() default "";
      String value() default "";
    }
    

    Second.java

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface Second {
        String name() default "";
        String value() default "";
    }
    

    Thing1.java

    public class Thing1 {
         @First(name = "1", value ="1")
         Object leftSideCase1;
         @Second(name = "1", value ="1")
         Object rightSideCase1;
    
         @First(value ="2")
         Object leftSideCase2;
         @First(name = "2")
         Object rightSideCase2;
    
         @First(value ="3")
         Object leftSideCase3;
         @First(value ="3")
         Object rightSideCase3;
    
         @First(name = "4", value ="4")
         Object leftSideCase4;
         @First(name = "4", value ="4")
         Object rightSideCase4;
    }
    

    Example.java

    public class Example {
    
    
        public static void main(String[] args) throws NoSuchFieldException {
            String [][] fieldNameOfCases = {
                    {"leftSideCase1","rightSideCase1"},
                    {"leftSideCase2","rightSideCase2"},
                    {"leftSideCase3","rightSideCase3"},
                    {"leftSideCase4","rightSideCase4"},
            };
    
            // Loop through the list of field names, paired up by test case
            // Note: It's the construction of Thing1 that matches your question's
            // "sample input():"
            for(int index=0; index < fieldNameOfCases.length; index++) {
                Annotation leftSideAnnotation = getAnnotation(Thing1.class, fieldNameOfCases[index][0]);
                Annotation rightSideAnnotation = getAnnotation(Thing1.class, fieldNameOfCases[index][1]);
                System.out.println(equal(leftSideAnnotation, rightSideAnnotation));
            }
        }
    
        private static Annotation getAnnotation(Class<Thing1> thing1Class, String fieldName) throws NoSuchFieldException {
            Field classMemberField = Thing1.class.getDeclaredField(fieldName);
            Annotation[] annotations = classMemberField.getAnnotations();
            // ASSUME ONE ANNOTATION PER FIELD
            return annotations[0];
        }
    
        // This is my solution to the question
        public static boolean equal(Annotation a1, Annotation a2) {
           if(a1.getClass() != a2.getClass()) {
               return false;
           }
           if(a1 instanceof First) {
               if( ((First)a1).name().equals(((First)a2).name())  &&
                   ((First)a1).value().equals(((First)a2).value()) ) {
                   return true;
               }
               return false;
           }
           // Its annoying we can't leverage inheritance with the custom annotation
           // to remove duplicate code!! 
           if(a1 instanceof Second) {
                if( ((Second)a1).name().equals(((Second)a2).name())  &&
                    ((Second)a1).value().equals(((Second)a2).value()) ) {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
    

    注意:我没有引入在 First 和 Second(自定义注释)中使用的 NamePairValue 持有者,因为这与“示例 input():”不匹配 完全强>!

    有关此样式/解决方案的详细信息,请参阅此堆栈跟踪。 How to extend Java annotation?

    这个问题已有 10 年历史,但没有按照 Roman 的要求回答该问题。 4k 观看次数,我希望这对某人有所帮助!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 2016-12-24
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 2010-12-07
      相关资源
      最近更新 更多