2

私はJavaの注釈の大ファンですが、自分で作成するたびにGoogleのReflectionsまたはScannotationsを含める必要があるのは首の痛みです。

コンテナなどの助けを借りずに、Javaがアノテーションを自動的にスキャンして適切に使用できることについてのドキュメントを見つけることができませんでした。

質問: Javaの基本的なことを見逃したことがありますか、それとも手動のスキャンとチェックが必要になるようにアノテーションが常に設計されていましたか?注釈を処理する組み込みの方法はありますか?

さらに明確にするために

もう少しプログラム的にJavaのアノテーションにアプローチできるようにしたいと思います。たとえば、のを作成したいとしListますCar。これを行うには、リストにデータを入力できるクラスでリストに注釈を付けます。例えば:

@CarMaker
List<Car> cars = new List<Car>();

この例では、CarMakerJavaがアノテーションにアプローチします。Javaは取引を成立させ、提供したい車の数を尋ねます。CarMaker含める車のリストを提供するのは、注釈/クラス次第です。@CarTypeこれは、アノテーションとCarインターフェースを備えたすべてのクラスである可能性があります。

別の見方をすれば、次のようなものを作成したいことがわかっている場合は、次のようにList<Car> cars注釈を付けることができます@ListMaker<Car>。これListMakerはJavaに組み込まれているものです。で注釈が付けられたすべてのクラスを検索し、@CarTypeそれに応じてリストにデータを入力します。

4

4 に答える 4

4

独自のアノテーションを作成して、独自のクラスに適用できます。

注釈を実行時に検出可能に指定すると、リフレクションを使用して簡単に処理できます。

たとえば、次のようなものを使用して、Funkyアノテーションでマークされたクラスの各フィールドの名前を出力できます。

for (Field someField : AnnotatedClass.getClass().getDeclaredFields()) {
    if (someField.isAnnotationPresent(Funky.class)) {
        System.out.println("This field is funky: " + someField.getName());
    }
}

ファンキーアノテーションを宣言するコードは次のようになります。

package org.foo.annotations;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Funky { }

アノテーションを使用するクラスは次のとおりです。

package org.foo.examples;

import org.foo.annotations.Funky;

public class AnnotatedClass {
    @Funky
    private  String   funkyString;
    private  String   nonFunkyString;
    @Funky
    private  Integer  funkyInteger;
    private  Integer  nonFunkyInteger;
}

アノテーションについてもう少し読んでください。

上記で使用したクラスのjavadocは次のとおりです。


私はあなたの車の例を理解しようとしていますが、あなたが望むものに従うかどうかはわかりません。

車を拡張し、さまざまな車関連の注釈でマークされたオブジェクト(ジャガー、ポルシェ、フェラーリ、起亜)のリストがある場合は、注釈に基づいてリストをフィルタリングするオブジェクトを作成できます。

コードは次のようになります。

@WorldsFinestMotorCar
class Jaguar extends Car {
    // blah blah
}

@BoringCar
class Porche extends Car {
    // blah blah
} 

@BoringCar
class Ferrari extends Car {
    // blah blah
}

@IncredibleCar
class Kia extends Car {
    // blah blah
}

特定の注釈がない車をリストから削除 するAnnotationFilterクラスを実装できます。

次のようになります。

List<Car> carList = getListOfRandomCars();
AnnotationFilter<Car> annoFilter = new AnnotationFilter<Car>(BoringCar.class);
List<Car> boringCars = annoFilter.filter(carList);

それはあなたがやりたいことですか?

もしそうなら、それは間違いなく行うことができます。

AnnotationFilterの実装は、次のようになります。

public class AnnotationFilter<T> {
    private Class filterAnno;

    public AnnotationFilter(Class a) {
        filterAnno = a;
    }

    public List<T> filter(List<T> inputList) {
        if (inputList == null || inputList.isEmpty()) {
            return inputList;
        }
        List<T> filteredList = new ArrayList<T>();
        for (T someT : inputList) {
            if (someT.getClass().isAnnotationPresent(filterAnno)) {
                filteredList.add(someT);
            }
        }
        return filteredList;
    }
}

それがあなたが求めているものではない場合は、特定の例が役立ちます。

于 2012-08-14T03:48:37.397 に答える
1

Javaにはそのようなものは何も組み込まれていません。そのため、Reflectionsが登場しました。あなたが言っていることほど特別なものは組み込まれていません。

于 2012-08-14T04:22:12.830 に答える
0

ユーザー定義の注釈:日常生活で遭遇する可能性のあるオブジェクトに注釈を付ける方法を見ていきます。オブジェクト情報をファイルに永続化したいとします。この目的には、Persistableと呼ばれる注釈を使用できます。重要なことは、情報が保存されるファイルについて言及したいということです。Annotation自体の宣言内にfileNameというプロパティを含めることができます。永続化可能な注釈の定義を以下に示します。

Persistable.java

@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
    public @interface Persistable
    {
        String fileName();
    }
于 2012-08-14T04:07:15.563 に答える
0

アノテーションは、クラスの要素にタグを付ける方法にすぎません。これらの注釈がどのように解釈されるかは、これらの注釈を定義するコード次第です。

注釈を処理する組み込みの方法はありますか?

注釈は非常に多くの異なる方法で使用されるため、注釈を処理するためのいくつかの「組み込みの方法」を思い付くのは困難です。コードの動作にまったく影響を与えないソースレベルのアノテーション(やなど@Override)があります。@Deprecated次に、通常は特定のライブラリに非常に固有のランタイムアノテーションがあります。JAXBのバインディングアノテーションはa内でのみ意味がありJAXBContext、Springの自動配線アノテーションは。内でのみ意味がありApplicationContextます。Javaは、これらのアノテーションを使用するクラスを調べるだけで、これらのアノテーションをどのように処理するかをどのように知ることができますか?

于 2012-08-14T04:10:25.280 に答える