当前位置: 首页 > 面试题库 >

Java-如何在单个参数中获取多个注释?

姚自强
2023-03-14
问题内容

如果我有这样的方法:

   testLink(@LinkLength(min=0, max=5) List<@LinkRange(min=5, max=9) Integer> link) { ... }

如何同时获取@LinkLength和@LinkRange批注?


问题答案:

我假设您想反射地访问这些注释。这是一个例子:

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;

public class Main {

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.PARAMETER, ElementType.TYPE_USE})
  public @interface Foo {

    String value();
  }

  public static void bar(@Foo("parameter") List<@Foo("type_use") Integer> list) {}

  public static void main(String[] args) throws NoSuchMethodException {
    Method method = Main.class.getMethod("bar", List.class);

    // get annotation from parameter
    Parameter parameter = method.getParameters()[0];
    System.out.println("PARAMETER ANNOTATION = " + parameter.getAnnotation(Foo.class));

    // get annotation from type argument used in parameter
    AnnotatedParameterizedType annotatedType =
        (AnnotatedParameterizedType) parameter.getAnnotatedType();
    AnnotatedType typeArgument = annotatedType.getAnnotatedActualTypeArguments()[0];
    System.out.println("TYPE_USE ANNOTATION  = " + typeArgument.getAnnotation(Foo.class));
  }
}

输出以下内容:

PARAMETER ANNOTATION = @com.example.Main$Foo(value="parameter")
TYPE_USE ANNOTATION  = @com.example.Main$Foo(value="type_use")

以下是使用的方法:

  • Class#getMethod(String,Class...)

    • 只会得到一个公共方法。要获取非公开方法,请参见Class#getDeclaredMethod(String,Class...)
    • Executable#getParamaeters()

    • Method从延伸Executable

    • Parameter#getAnnotatedType()
  • AnnotatedParameterizedType#getAnnotatedActualTypeArguments()

  • AnnotatedElement#getAnnotation(Class)

    • MethodParameter和和AnnotatedType(和其他类型)全部继承AnnotatedElement

上面的示例充分利用了有关该bar方法的知识。换句话说,我知道有一个参数,知道Parameter#getAnnotatedType()会返回AnnotatedParameterizedType,而且我知道参数化类型有一个类型实参。反省地扫描任意类时,不会提前知道此信息,这意味着您将必须添加适当的检查并仅在适当的时候执行某些操作。例如:

AnnotatedType type = parameter.getAnnotatedType();
if (type instanceof AnnotatedParameterizedType) {
  // do something...
}


 类似资料:
  • 每当调用RESTendpoint时,我都需要记录。我正在尝试使用Spring AOP来做到这一点。 在其他事情中,我需要延长endpoint的名称。一、 我需要读出映射注释的值。 我想以通用的方式解决这个问题。即“给我映射的值,无论确切的映射是什么”。 所以我现在所做的基本上就是这个答案中提出的:https://stackoverflow.com/a/26945251/2995907 然后我将传递

  • 问题内容: 假设我有这个功能: 我想这样称呼它: 当然,不能用这种方法来完成,因为Postgres试图用该名称和三个不存在的参数来查找函数。 我试图用引号引起来,但在这种情况下,参数解释错误: data1’,’data2’,’data3 ,就像一个字符串一样。 有没有一种方法可以在参数中放置多个值,以便IN子句可以识别它? 问题答案: 您的函数将不会被创建。之后是句法废话。 无论哪种方式,带有 参

  • 问题内容: 例 问题,如何获得单一值,例如: 问题答案: 查看您的中的键和缩进: …等等

  • 但是,当我试图将此代码更改为以下代码时,我得到了一个错误-错误:Main method,在类MyClass中找不到,请将Main method,定义为:public static void Main(string[]args)。我需要接收owner和consumerName作为我的程序的参数/输入。 ,这是怎么做到的?

  • 我有一个大型多维数组(约1900万个元素),其中包含多个不同属性的联合概率。 数组非常稀疏,我只对概率非零的单元格感兴趣。 但是,在筛选数组中的非零元素时,我无法检索筛选值的维度名称(对应于各种属性值)。 以下是一个玩具示例: 我可以获得与某个标准匹配的单元格的索引值(此处, 但我无法使用上述索引值并找出它们是什么水果组合,因为在查找特定单元格值时,DIMNAME会被删除: 我尝试将数组转换为da

  • 问题内容: 我创建了自己的注释类型,如下所示: 并将其附加到一个类上: 我试图通过反射来获得类注释,如下所示: 但它没有打印任何内容。我究竟做错了什么? 问题答案: 默认的保留策略是,默认情况下,注释信息在运行时不保留: 批注由编译器记录在类文件中,但VM在运行时无需保留。这是默认行为。 而是使用: 注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以通过反射方式读取它们。 …您使用met