如何将注释类型作为方法参数传递?

Posted

技术标签:

【中文标题】如何将注释类型作为方法参数传递?【英文标题】:How to pass Annotation Type as a method parameter? 【发布时间】:2019-04-01 07:27:57 【问题描述】:

有一种方法可以处理类似的注释

public void getAnnotationValue(ProceedingJoinPoint joinPoint)

     MethodSignature methodSignature = (MethodSignature) joinPoint.getStaticPart().getSignature();
     Method method = methodSignature.getMethod();
     Annotation annotation = method.getParameterAnnotations()[0][0];
    RequestHeader requestParam = (RequestHeader) annotation;
    System.out.println(requestParam.value());

我想把它转换成一个接受 joinPoint 和 Annotation Type 之类的通用方法

getAnnotationValue(joinPoint, RequestHeader);

我尝试使用:

public void getAnnotationValue(ProceedingJoinPoint joinPoint, Class<? extends Annotation> annotationType)
    
         MethodSignature methodSignature = (MethodSignature) joinPoint.getStaticPart().getSignature();
         Method method = methodSignature.getMethod();
         Annotation annotation = method.getParameterAnnotations()[0][0];
        annotationType requestParam = (annotationType) annotation;
        System.out.println(requestParam.value());
    

但是提示错误type unresolved error?如何处理它并将注释值传递给该函数!

【问题讨论】:

很遗憾 type 在 java 中不是变量,不过你可以使用 Class @Andronicus 我尝试使用 Class extends Annotation> 但它提示相同的错误说明类型未解析 在这种情况下,请更新您的问题以提供minimal reproducible example。另外:当您希望确保其他用户收到您为他们提供的 cmets 时,请使用 @user 语法。 【参考方案1】:

你能做的“最好的”事情:

public void foo(Class<? extends java.lang.annotation.Annotation> annotationClass)  ...

Annotation 没有特定的“类型”类,但您可以使用普通的 Class 对象,并简单地表示您期望 Annotation 基类的子类。

【讨论】:

我试过了,但是提示输入未解决的错误!! @KNDheeraj 我想通了。因此,我建议您阅读minimal reproducible example 并相应地增强您的问题。请给我们一个显示编译器错误的最小示例。否则我们帮不了你。【参考方案2】:

您想要做的只是不那样工作。问题不在于方法签名,而是您对如何在 Java 中使用类型的错误理解。在这一行...

annotationType requestParam = (annotationType) annotation;

...你有两个错误:

您不能使用annotationType requestParam 声明变量,因为annotationType 不是类名文字而是变量名。这是一个语法错误,编译器会这样标记它。 您不能使用(annotationType) annotation 来进行转换,原因与第一种情况相同。 Java 不能那样工作,代码是无效的。

话虽如此,稍后您的代码假定捕获的注释类有一个方法value(),这对于某些注释类可能碰巧是正确的,但在一般情况下不起作用。但是假设该方法确实存在于您调用辅助方法的所有情况下,您可以将其更改为如下所示:

public void getAnnotationValue(JoinPoint joinPoint) 
  MethodSignature methodSignature = (MethodSignature) joinPoint.getStaticPart().getSignature();
  Method method = methodSignature.getMethod();
  Annotation annotation = method.getParameterAnnotations()[0][0];
  Class<? extends Annotation> annotationType = annotation.annotationType();
  try 
    System.out.println(annotationType.getMethod("value").invoke(annotation));
   catch (Exception e) 
    throw new SoftException(e);
  

IMO 这很丑陋,而且编程不好。但它编译并运行。 BTW,如果注解类型没有value() 方法,你会看到NoSuchMethodException 被抛出。

我认为您正在遭受XY problem 的困扰。你不是在描述你想解决哪个实际问题,而是你认为解决方案应该是什么样子,让你自己和其他人盲目地寻找更好的方法来解决问题。因此,我的示例代码可能并不能真正解决您的问题,而只是让您丑陋的解决方案以某种方式发挥作用。这与好的设计不同。

【讨论】:

以上是关于如何将注释类型作为方法参数传递?的主要内容,如果未能解决你的问题,请参考以下文章

如何将布尔数据类型作为存储过程的参数传递?

如何通过扫描仪将 LocalDate 类型作为参数传递?

如何将匿名类型作为参数传递?

C#如何将类型Type作为泛型T的参数T传递

将具有类型参数的类作为Java中泛型方法的类型参数传递

如何在将对象作为泛型参数传递时使用它的基础类型