简体   繁体   中英

How to check equality of annotations?

How would you implement this method:

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

Sample input ():

@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")

Sample output:

false
false
true
true

As you can see, the expected behavior of equal is clear and similar to expected behavior of standard equals method of regular objects in java (the problem is that we cannot override equals for annotations).

Are there any libs or standard implementations?

Doesn't the overriden equals for Annotation work? Maybe I don't understand your question.

If you want to check whether a1 and a2 are the same annotation. Try this: a1.annotationType().equals(a2.annotationType())

The annoying part of my answer is I can not extend a custom annotation (in the sense of inheritance). That would have simplified the equals method.

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;
    }
}

Note: I did not introduce a NamePairValue holder to use within First, and Second (custom annotation) because this didn't match the "sample input():" exactly !

See this Stack Trace for details for this style / solution. How to extend Java annotation?

This question is 10 years old but the question was not answered as asked by Roman. With 4k views, I hope this helps someone !!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM