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

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

ただいまの
回答率

90.37%

  • Java

    15107questions

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

  • JSON

    1345questions

    JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

アノテーションの定義メソッドをリフレクションで取りたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,663

ipadcaron

score 1343

Java8

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface An {
   String x() default "OK";
}

public static class AA {
   @An
   String XX;
}

public static void main(String[] args) {

}

すみません、質問です。
アノテーション An の x をリフレクションで取りたいんですけど方法ありますか?
もちろん、"x" を固定で指定せず、すべて Field, Method などを使って、An に定義されているアノテーション一覧を
取りたいです。
インターフェースの拡張なので、RUNTIME時点で、プロキシーが介入するため、

public class AnoTest {

    @Columns(id = "DFL")
    private Double  val = 12.5;

    public static void main(String[] args) throws Throwable {

        AnoTest ano = new AnoTest();

        Field f = ano.getClass().getDeclaredField("val");

        System.out.println("-------- annotation.toString.");
        Columns c = f.getAnnotation(Columns.class);

        System.out.println(c);

        System.out.println("-------- fields.");
        for (Field ff : c.getClass().getDeclaredFields()) {
            System.out.println(ff);

        }
        System.out.println("-------- methods.");

        for (Method m : c.getClass().getMethods()) {


            System.out.println(m + " => Decl => " + m.getDeclaringClass());

        }


    }

}


これでやると、最後の system.out でやまほどメソッドが出てくるのですが、$Proxy1 を固定で参照するのはイマイチです。固定で、つまり、"$proxy." で始まるメソッド定義のメソッド名、で取るのは最後の手段としたいです。

よろしくお願いします。

最終的には、JSON 配列になります。

Columns.java

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Columns {
    // Requires
    String id();

    // Options
    String enShortNm() default "";
    String enLongNm() default "";
    String jpShortNm() default "";
    String jpLongNm() default "";
    String prefix() default "";
    String suffix() default "";

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

package mc.main;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import mc.ann.Columns;
import mc.dto.RateDto;

public class AnoTest2 {

    public interface An {
        String vale();
    }

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface An2 {
        String vale();
    }

    public static void main(String[] args) throws Throwable {

        new AnoTest2().test();
    }

    public void test() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        An2 a = new An2() {

            @Override
            public String vale() {
                // TODO 自動生成されたメソッド・スタブ
                return null;
            }

            @Override
            public Class<? extends Annotation> annotationType() {
                // TODO 自動生成されたメソッド・スタブ
                return null;
            }

        };

        for (Method m : An2.class.getMethods()) {
            System.out.println(m.getName() + "=>" + m.getDeclaringClass().getName());
        }

        RateDto dto = new RateDto();
        dto.setGbp(1.23);
        dto.setJpn(2.56);
        dto.setUsd(4.56);

        for (Field f : dto.getClass().getDeclaredFields()) {
            System.out.println("[F]:" + f.getName());
            Columns col = f.getAnnotation(Columns.class);

            int count = 0;
            for (Method m : Columns.class.getDeclaredMethods()) {
                Class<?> clazz = m.getDeclaringClass();
                if (m.getDeclaringClass().equals(Columns.class)) {
                    System.out.println(count++ + "::" + f.getName() + "=>" + col + "=>" + clazz.getName());

                    Object ob = m.invoke(col);
                    System.out.println(m.getName() + " called , => " + ob.getClass().getName() + "=>" + ob);
                }
            }
        }
    }
}

eclipse の C+SP で普通に見えるんで再度やってみたら、普通に取れました。
解決しました、すみません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Java

    15107questions

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

  • JSON

    1345questions

    JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。