2015-02-06 72 views
3

在Java中,可以使界限类型参数必须从特定的类或接口(例如,受限注的类型参数受注释约束

public class Box<T extends MyClass> { 
    T t 
    ... 
} 

是否有我可以通过注释绑定,以便T的值只能是具有特定注释的类?

+5

我不认为你可以,但你可以让这些类实现标记接口(一个没有方法的接口)。 – assylias 2015-02-06 23:04:50

+1

我很确定有些持久性框架会这样做,而且他们必须在运行时执行此操作。我想你可能可以用[注释处理器]做一些事情(http://docs.oracle.com/javase/7/docs/technotes/guides/apt/GettingStarted.html),但那会是超语言的也很复杂。 – markspace 2015-02-06 23:27:14

+0

在运行时检查很简单:'t.getClass()。isAnnotationPresent(annotationClass)' – duckstep 2015-02-11 01:06:22

回答

1

不幸的是,没有办法在java AFAIK中表达它。 <T annotatedWith MyAnnotation>会在某些情况下如此方便,但它会增加一个新的关键字和诚实泛型是相当困难;)

否则,对于注释,因为@duckstep说,这很容易在运行时用

t.getClass().isAnnotationPresent(annotationClass) 
检查

不过,对于注释处理器而言,API处理起来要困难得多。下面是一些代码,如果它可以帮助一些人:

private boolean isAnnotationPresent(TypeElement annotationTypeElement, String annotationName) { 
    for (AnnotationMirror annotationOfAnnotationTypeMirror : annotationTypeElement.getAnnotationMirrors()) { 
     TypeElement annotationOfAnnotationTypeElement = (TypeElement) annotationOfAnnotationTypeMirror.getAnnotationType().asElement(); 
     if (isSameType(annotationOfAnnotationTypeElement, annotationName)) { 
      return true; 
     } 
    } 
    return false; 
} 

private boolean isSameType(TypeElement annotationTypeElement, String annotationTypeName) { 
    return typeUtils.isSameType(annotationTypeElement.asType(), elementUtils.getTypeElement(annotationTypeName).asType()); 
} 
2

用Java 8开始,你可以写

public class Box<T extends @MyAnno MyClass> { 
... 
} 

与任何Java注释,执行语义,你需要使用一个注解处理器。 Checker Framework是一种为您执行语义的注释处理工具:如果您尝试使用缺少@MyAnno注释的类型参数尝试实例化Box类型,则可以将其配置为发出错误。