簡體   English   中英

如何檢查注釋的相等性?

[英]How to check equality of annotations?

你將如何實現這個方法:

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 )。

是否有任何庫或標准實現?

覆蓋是否等於 Annotation工作? 也許我不明白你的問題。

如果要檢查a1和a2是否是相同的注釋。 試試這個:a1.annotationType()。equals(a2.annotationType())

我的答案中令人討厭的部分是我無法擴展自定義注釋(在繼承的意義上)。 這將簡化 equals 方法。

首先.java

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

第二個.java

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

東西1.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;
}

例子.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 持有者,因為這與“示例輸入():”不完全匹配!

有關此樣式/解決方案的詳細信息,請參閱此堆棧跟蹤。 如何擴展Java注解?

這個問題已經有 10 年的歷史了,但問題沒有按照 Roman 的要求回答。 擁有4k 觀看次數,我希望這對某人有所幫助!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM