2012-04-11 14 views
4

Ich bin interessiert so etwas wie diese dabei:Java Annotation zum Erzwingen von statischen Variablen oder statischen Methoden?

public interface Foo { 

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

} 

und

public interface Foo { 

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

} 

ohne die Statik, diese OOP ist 101, aber es kann nicht in Standard-oop java erfolgen. Ich frage mich, ob es eine Anmerkung gibt, die dieses Verhalten sicherstellen würde?

edit:

ich bin daran interessiert, eine Reihe von Optionen bei der Angabe, die definiert, wie für „konfigurierbar“ Objekte Dinge einzustellen. Dies könnte Befehlszeilen-Flags, etc. sein

+1

Ich habe keine Ahnung ... aber ich bin neugierig, wohin Sie damit gehen. vielleicht gibt es einen einfacheren Weg ... – kritzikratzi

+1

verwandt: [Warum kann ich statische Methoden in einer Schnittstelle nicht deklarieren?] (http://stackoverflow.com/questions/21817/why-cant-i-declare-static-methods -in-interface) –

+1

siehe auch: [Java-Schnittstelle statische Methode Workaround?] (http://stackoverflow.com/questions/1724502/java-interface-static-method-workaround) –

Antwort

3

Ich vermute, was Sie wollen, eine Methode, wie

public void callFoo(Class<?> clazz) 

zu haben ist, und Sie wollen sicherstellen, dass clazz ein Verfahren public static void foo() hat.

Ich dachte eine Weile darüber nach und keine der Techniken, die Ihnen in den Sinn kommen, werden Sie dorthin bringen. Sie können AnnotationProcessor verwenden, um sicherzustellen, dass alle Klassen, die mit einer bestimmten Annotation versehen sind, eine bestimmte Methode oder eine bestimmte Annotation haben (und einen Kompilierungsfehler generieren). Es gibt jedoch keine Möglichkeit, die übergebenen Argumente zu kompilieren (Class) zu callFoo(Class<?> clazz) sind mit Ihrer Anmerkung kommentiert.

Hier ist ein AnnotationProcessor, die Sie auf halbem Weg dorthin kommt:

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; 
    } 

} 

Letztendlich würde ich Ihnen vorschlagen, entweder erlauben es etwas erzwungen zur Laufzeit oder Ihre Redesign Ihren Code, so dass Sie statische Methoden nicht verwenden müssen .

Verwandte Themen