2016-07-20 38 views
2

Java 8 ermöglicht Dinge wie:Sind Anmerkungen zu einem Typparameter in Laufzeit verfügbar?

public List<@NonNull String> names; 

Aber ist es eine Möglichkeit, diese Anmerkung in Runtime zuzugreifen, oder ist es nur Plugins Compiler?

Es gibt neue Method#getAnnotatedReturnType, den Zugriff auf Anmerkungen zu dem Rückgabetyp liefert, so dass ich habe gehofft, ParameterizedType jetzt so etwas wie getActualAnnotatedTypeArguments haben würde, die die gleichen für generische Typargumente tun würden, aber es ist nicht vorhanden ...

+3

Ich habe keine Zeit, es zu überprüfen, aber ein Subtyp von Type ist TypeVariable, die AnnotatedElement erweitert. Hat das was du brauchst? – yshavit

+1

Ah, gefunden! Der korrekte neue Typ ist AnnotatedParameterizedType. Ich habe es beim Debuggen gefunden. Danke, dass du mich in die richtige Richtung schubst! – kaqqao

+0

@yshavit Vielen Dank, dass Sie darauf hingewiesen haben! Es war sehr unübersichtlich, wie man Typ-Parameter einer gegebenen Klasse kommentiert bekommt. – kaqqao

Antwort

4

Die neue API setzt die Tradition der vielen instanceof s und Art erfordern wirft:

import java.lang.annotation.*; 
import java.lang.reflect.*; 
import java.util.*; 
import java.util.stream.*; 

public class AnnoTest { 
    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.TYPE_USE) 
    @interface NonNull {} 

    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.TYPE_USE) 
    @interface NonEmpty {} 

    List<@NonNull String> list; 
    Map<@NonNull Integer, @NonNull @NonEmpty Set<String>> map; 
    Object plain; 

    public static void main(String[] args) throws ReflectiveOperationException { 
     for(Field field: AnnoTest.class.getDeclaredFields()) { 
      AnnotatedType at = field.getAnnotatedType(); 
      System.out.println(formatType(at)+" "+field.getName()); 
     } 
    } 
    static CharSequence formatType(AnnotatedType type) { 
     StringBuilder sb=new StringBuilder(); 
     for(Annotation a: type.getAnnotations()) sb.append(a).append(' '); 
     if(type instanceof AnnotatedParameterizedType) { 
      AnnotatedParameterizedType apt=(AnnotatedParameterizedType)type; 
      sb.append(((ParameterizedType)type.getType()).getRawType().getTypeName()); 
      sb.append(Stream.of(apt.getAnnotatedActualTypeArguments()) 
       .map(AnnoTest::formatType).collect(Collectors.joining(",", "<", ">"))); 
     } 
     else sb.append(type.getType().getTypeName()); 
     return sb; 
    } 
} 

Siehe auch das Ende der this answer für ein Beispiel, die anderen Szenarien wie Typ Variablen, wilde Kartentypen und Arrays Handhabung.

3

Es gibt in der Tat eine Methode getAnnotatedActualTypeArguments, aber in AnnotatedParameterizedType, nicht in ParameterizedType, wo ich danach gesucht habe.