4

私はこのようなことをすることに興味があります:

public interface Foo {

  public static "abstract" Bar SOME_BAR; // subclasses define one of these

}

public interface Foo {

  public static "abstract" Baz buildABas(...); // subclasses define this method 

}

静的でない場合、これは OOP 101 ですが、標準の oop Java では実行できません。この動作を保証する注釈があるのだろうか?

編集:

「構成可能な」オブジェクトの設定方法を定義する一連のオプションを指定することに興味があります。これは、コマンドライン フラグなどである可能性があります。

4

1 に答える 1

3

あなたが望んでいるのは、次のようなメソッドを持つことだと思います

public void callFoo(Class<?> clazz)

clazzそして、 method があることを確認したいと思いますpublic static void foo()

私はこれについてしばらく考えましたが、頭に浮かぶテクニックはどれもあなたをそこに連れて行きません. を使用しAnnotationProcessorて、特定の注釈で注釈が付けられたクラスに特定のメソッドまたは何があるかを確認できます (そうでない場合はコンパイル エラーを生成します)。ただし、(コンパイル時に)Class渡された引数callFoo(Class<?> clazz)があなたの注釈で注釈を付けます。

ここにあるのは AnnotationProcessor で、そこに到達することができます。

import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;


@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("so.Foo")
public class FooAnnotationProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {

        TypeElement foo = processingEnv.getElementUtils().getTypeElement("so.Foo");
        Set<? extends Element> classes = roundEnv.getElementsAnnotatedWith(foo);
        Messager messenger = processingEnv.getMessager();
        for (Element e : classes) {
            boolean found = false;
            for (Element method : e.getEnclosedElements()) {
                messenger.printMessage(Diagnostic.Kind.ERROR, 
                        method.getSimpleName());
                if (method.getKind() == ElementKind.METHOD && method.getSimpleName().toString().equals("getInstance")) {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                messenger.printMessage(Diagnostic.Kind.ERROR, 
                    "The following class does not implement getInstance : " + e.getSimpleName(),e);
            }
        }
        return true;
    }

}

最終的には、実行時に強制されるものにするか、静的メソッドを使用する必要がないようにコードを再設計することをお勧めします。

于 2012-05-03T15:41:43.047 に答える