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 开发者_StackOverflow社区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!!
精彩评论