アノテーションとequals()
JSR-299で、アノテーションを比較する概念が出てくるので、ちょっと色々テストしてみる。
--- Foo.java ---
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Target({METHOD, CONSTRUCTOR, FIELD})
@Retention(RUNTIME)
public @interface Foo {
}
--- Bar.java ---
import java.lang.annotation.Annotation;
public class Bar {
@Foo int foo1;
@Foo int foo2;
public static void main(String[] args) throws Exception {
Annotation foo1 = Bar.class.getDeclaredField("foo1").getAnnotation(Foo.class);
Annotation foo2 = Bar.class.getDeclaredField("foo2").getAnnotation(Foo.class);
System.err.println("foo1 = " + foo1);
System.err.println("foo2 = " + foo2);
System.err.println(foo1 == foo2);
System.err.println(foo1.equals(foo2));
}
}
結果
shanai@shanai-laptop:/tmp$ java -cp . Bar
foo1 = @Foo()
foo2 = @Foo()
false
true
別インスタンスのようだけど、equals()をオーバーライドしてないのに、equals()比較はtrueになっている。メンバを持たせていると、
--- Foo2.java ---
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Target({METHOD, CONSTRUCTOR, FIELD})
@Retention(RUNTIME)
public @interface Foo2 {
String[] value();
}
--- Bar2.java ---
import java.lang.annotation.Annotation;
public class Bar2 {
@Foo2({"Hello", "World"}) int foo1;
@Foo2({"Hello", "World"}) int foo2;
@Foo2({"Hello"}) int foo3;
public static void main(String[] args) throws Exception {
Annotation foo1 = Bar2.class.getDeclaredField("foo1").getAnnotation(Foo2.class);
Annotation foo2 = Bar2.class.getDeclaredField("foo2").getAnnotation(Foo2.class);
Annotation foo3 = Bar2.class.getDeclaredField("foo3").getAnnotation(Foo2.class);
System.err.println("foo1 = " + foo1);
System.err.println("foo2 = " + foo2);
System.err.println("foo3 = " + foo3);
System.err.println("foo1 == foo2: " + (foo1 == foo2));
System.err.println("foo1 == foo3: " + (foo1 == foo3));
System.err.println("foo1.equals(foo2): " + foo1.equals(foo2));
System.err.println("foo1.equals(foo3): " + foo1.equals(foo3));
}
}
結果
shanai@shanai-laptop:/tmp$ java Bar2
foo1 = @Foo2(value=[Hello, World])
foo2 = @Foo2(value=[Hello, World])
foo3 = @Foo2(value=[Hello])
foo1 == foo2: false
foo1 == foo3: false
foo1.equals(foo2): true
foo1.equals(foo3): false
ふ〜ん、やっぱりメンバの一致まで見てくれるんだ。おもしろいな。この挙動は、Annotation.equals()のAPI仕様書に記載されている。








