質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

3518閲覧

インターフェースに定義されたメソッドのアノテーションの取得方法について

kakusuke

総合スコア80

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2015/09/10 13:20

編集2015/09/11 01:10

特定の実体クラスのメソッドから、インターフェースに定義された同じメソッドについてるアノテーションを簡単に取る方法しりませんか?

java

1public interface A { 2 @Foo 3 String hoge(String str); 4 String hoge(Integer i); 5}

java

1public class B implements A { 2 @Override String hoge(String str) { return str; } 3 @Override String hoge(Integer i) { return String.valueOf(i); } 4}

のようなインターフェースとクラスがあり、

java

1Method method = B.class.getDeclaredMethod("hoge", new Class[] { String.class });

のようなメソッドがすでに取得されているとき、このmethodからA@Fooを取得しにいくための最適解を知りたいです。

method.getDeclaringClass().getInterfaces()[0].getMethod(method.getName(), method.getParameterTypes()).getAnnotations() のようにすれば思うようなことは出来ますが、
子クラスのメソッドのパラメータ型の境界が変わってたりした時に大丈夫なの、
とか、Method#getSuperMethodみたいなもうちょっと素直なAPIないの、とかが聞きたい点です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

スマートでないにしろ、Overrideしちゃうのでしょうがないといえばしょうがないですね。
残念ながら子クラスからたどるしかないです。
ある程度自由を持たせるなら、がっちり書かないで面倒ではあるもののゆるく書く方が良いかもです。

Foo.java

Java

1import java.lang.annotation.ElementType; 2import java.lang.annotation.Inherited; 3import java.lang.annotation.Retention; 4import java.lang.annotation.RetentionPolicy; 5import java.lang.annotation.Target; 6 7@Retention(RetentionPolicy.RUNTIME) 8@Target(ElementType.METHOD) 9@Inherited 10public @interface Foo { 11 String value(); 12} 13

A.java

Java

1public interface A { 2 @Foo("Testです") 3 String hoge(String str); 4 String hoge(Integer i); 5} 6

Test.java(Bと思って下さい)

Java

1import java.lang.annotation.Annotation; 2import java.lang.reflect.Method; 3import java.util.Arrays; 4 5public class Test implements A { 6 @Override 7 @Foo("TestString2") 8 public String hoge(String str) { return str; } 9 @Override 10 public String hoge(Integer i) { return String.valueOf(i); } 11 12 public static void main(String[] args) { 13 14 try { 15 Class<Test> clazz = Test.class; 16 17 if (clazz.getInterfaces() != null && clazz.getInterfaces().length > 0) { 18 for (Class<?> inf : clazz.getInterfaces()) { 19 Method[] mets = inf.getDeclaredMethods(); 20 for (Method met : mets) { 21 if (Arrays.stream(met.getAnnotations()).anyMatch(p-> p instanceof Foo)) { 22 if (clazz.getDeclaredMethod(met.getName(), met.getParameterTypes()) != null ){ 23 dump("メソッド", met.getDeclaredAnnotations()); 24 } 25 } 26 27 } 28 } 29 } 30 31 } catch (SecurityException | NoSuchMethodException e) { 32 e.printStackTrace(); 33 } 34 35 } 36 37 public static void dump(String message, Annotation[] as) { 38 System.out.println(message); 39 for (Annotation a : as) { 40 System.out.println(a); 41 } 42 } 43} 44

投稿2015/09/11 02:42

編集2015/09/11 02:47
anonymouskawa

総合スコア856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakusuke

2015/09/11 04:27

やはりそういう泥臭いやり方しかないですかね・・・ ありがとうございます
guest

0

「@Fuga」と書かれていますが「@Foo」だと思っていいですか?
そもそもinheritsはJavaの場合implementsかな?とも思うのですが、もしかしてC#ですかね?
違うかな?(^ω^;)
Javaで考えたらアノテーションの実装の有無はisAnnotationPresentじゃないでしょうか?
境界が変わってもスーパークラスは規定があるはずですし、アノテーションは自作の場合、自分で実装するので十分チェック可能だと思います。
逆に、実現したいことから考えられた方がいいと思います。
やりたいことは理解できますが、なぜそうしないといけないのかの意見が知りたいです。
それによってスマートな書き方が変わるのではないかと思うのですが、如何でしょうか?

投稿2015/09/10 15:12

bvl

総合スコア45

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakusuke

2015/09/11 01:22

まず、インターフェースからAPTで自動生成された実装クラスをGuiceでそのインターフェースにバインドしています。 GuiceのInterceptor内で、実行時例外をキャッチして解析したあと、別の例外に整形して詰めなおして投げなおすということをしたいと思っています。 ただ、Interceptor内で参照できる実行メソッドは実装クラスのメソッドで、アノテーションが自動でコピーはされないです。 なので、`Method#isAnnotationPresent`では常に`false`が返ってきて、やれ困ったという状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問