我有这个案子:
public class SomeClass<T> {
public <@A1 S extends @A2 T> @A3 S myMethod() { ...}
}
我试图在绑定@A2
上获取T
注释。
这就是我所看到的,假设myMethod
是SomeClass.class.getDeclaredMethod("myMethod")
。为了便于阅读,删除了类型转换。
myMethod.getGenericReturnType().getAnnotations()
返回@A1
(正如我所料,我猜)myMethod.getGenericReturnType().getBounds()[0].getAnnotations()
返回没有(?? shoudn&#39;它是@A2
??)myMethod.getAnnotatedReturnType().getAnnotations()
返回@A3
(正如我所料,我猜)myMethod.getAnnotatedReturnType().getAnnotatedBounds()[0].getAnnotations()
返回没有(例如,我猜)似乎@A2
迷失了......这听起来并不合理。我做错了什么,或者这确实是一些奇怪的行为?
更新: 它确实是一个JDK错误,我报告了它并被接受为JDK-8191466
答案 0 :(得分:3)
可以通过AnnotatedType
层次结构检索所有类型注释,TypeVariable
除外,AnnotatedTypeVariable.getType()
的注释可以通过TypeVariable
检索,AnnotatedElement
是Method.getGenericReturnType()
的实例现在扩展AnnotatedType art = myMethod.getAnnotatedReturnType();
System.out.print(
Arrays.toString(art.getAnnotations())+" "+art.getType().getTypeName()+" -> ");
final boolean typeVariable = art instanceof AnnotatedTypeVariable;
if(typeVariable) System.out.print('<');
System.out.print(Arrays.toString(((AnnotatedElement)art.getType()).getAnnotations())+" ");
System.out.print(art.getType().getTypeName());
if(typeVariable) {
AnnotatedTypeVariable atv = (AnnotatedTypeVariable)art;
AnnotatedType[] annotatedBounds = atv.getAnnotatedBounds();
if(annotatedBounds.length>0) {
System.out.print(" extends ");
for(AnnotatedType aBound: annotatedBounds) {
System.out.print(Arrays.toString(aBound.getAnnotations())+" ");
System.out.print(aBound.getType().getTypeName()+", ");
}
}
System.out.println(">");
}
,恰好与[@A3()] S -> <[@A1()] S extends [@A2()] T, >
返回的对象相同。
因此,您可以检索所有信息,例如
((AnnotatedTypeVariable)myMethod.getAnnotatedReturnType()) .getAnnotatedBounds()[0].getAnnotations()
将打印
@A2
当您A2
的调用未提供@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE)
时,您应该重新检查instanceof
是否真的有Type
。
当然,这是仅处理您特定方法的“简化”版本。
要处理所有可能的情况,您需要更多AnnotatedType
来处理TypeVariable
和AnnotatedElement
的这些析取类型层次结构,尤其是在处理带注释的参数化类型和带注释的通用数组时类型。
如前所述,getAnnotatedBounds()
不同,因为它扩展了List<TypeVariable<?>> typeParameters = Arrays.asList(myMethod.getTypeParameters());
for(TypeVariable<?> tv: typeParameters) {
System.out.print("< "+Arrays.toString(tv.getAnnotations())+" "+tv.getName());
AnnotatedType[] annotatedBounds = tv.getAnnotatedBounds();
if(annotatedBounds.length > 0) {
System.out.print(" extends ");
for(AnnotatedType aBound: annotatedBounds) {
System.out.print(Arrays.toString(aBound.getAnnotations())+" ");
System.out.print(aBound.getType().getTypeName()+", ");
}
}
System.out.print("> ");
}
AnnotatedType art = myMethod.getAnnotatedReturnType();
System.out.print(Arrays.toString(art.getAnnotations())+" ");
int ix = typeParameters.indexOf(art.getType());
if(ix >= 0) System.out.print("[ref to type parameter #"+ix+"] ");
System.out.println(art.getType().getTypeName());
并且还有function something(pages,totalDutation){
// pages = 900
// totalDutation = 90
var printsPerMinute = pages / totalDutation //get the prints per minute!
var printsPerHour = Math.floor(printsPerMinute * 60) //calculate the prints made in one hour
var countOfHours = parseInt(totalDutation / 60) //divide the total duration by 60 to get the count of hours
var remainingPrints = (totalDutation % 60) * printsPerMinute //add the extra prints that didn't complete a whole hour.
var result = Array(countOfHours).fill(printsPerHour) //create an array and fill it.
if(remainingPrints) result.push(remainingPrints)
return result
}
方法。因此,在这种特定情况下,处理该方法的另一种方法是
public String method1(someparameters) {
//Calls methods of a different objects
result2 = object2.method2(someparams )
result3 = object3.method3(someparams)
// Does bunch of work in method1
...................
...................
return result
}