java中可以读取注解的值吗?

发布于 2024-10-04 10:05:59 字数 483 浏览 0 评论 0 原文

这是我的代码:

@Column(columnName="firstname")
private String firstName;
 
@Column(columnName="lastname")
private String lastName;

public String getFirstName() {
  return firstName;
}

public void setFirstName(String firstName) {
  this.firstName = firstName;
}

public String getLastName() {
  return lastName;
}

public void setLastName(String lastName) {
  this.lastName = lastName;
}

是否可以在另一个类中读取我的注释 @Column(columnName="xyz123") 的值?

this is my code:

@Column(columnName="firstname")
private String firstName;
 
@Column(columnName="lastname")
private String lastName;

public String getFirstName() {
  return firstName;
}

public void setFirstName(String firstName) {
  this.firstName = firstName;
}

public String getLastName() {
  return lastName;
}

public void setLastName(String lastName) {
  this.lastName = lastName;
}

Is it possible to read the value of my annotation @Column(columnName="xyz123") in another class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

不念旧人 2024-10-11 10:05:59

是的,如果您的列注释具有运行时保留,

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
    ....
}

您可以执行如下

for (Field f: MyClass.class.getFields()) {
   Column column = f.getAnnotation(Column.class);
   if (column != null)
       System.out.println(column.columnName());
}

更新:要获取私有字段,请使用

Myclass.class.getDeclaredFields()

Yes, if your Column annotation has the runtime retention

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
    ....
}

you can do something like this

for (Field f: MyClass.class.getFields()) {
   Column column = f.getAnnotation(Column.class);
   if (column != null)
       System.out.println(column.columnName());
}

UPDATE : To get private fields use

Myclass.class.getDeclaredFields()
断肠人 2024-10-11 10:05:59

当然是。这是一个示例注释:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    String testText();
}

和一个示例注释方法:

class TestClass {

    @TestAnnotation(testText="zyx")
    public void doSomething() {}
}

另一个类中打印 testText 值的示例方法:

Method[] methods = TestClass.class.getMethods();
for (Method m : methods) {
    if (m.isAnnotationPresent(TestAnnotation.class)) {
        TestAnnotation ta = m.getAnnotation(TestAnnotation.class);
        System.out.println(ta.testText());
    }
}

对于像您这样的字段注释没有太大不同。

Of course it is. Here is a sample annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    String testText();
}

And a sample annotated method:

class TestClass {

    @TestAnnotation(testText="zyx")
    public void doSomething() {}
}

And a sample method in another class that prints the value of the testText:

Method[] methods = TestClass.class.getMethods();
for (Method m : methods) {
    if (m.isAnnotationPresent(TestAnnotation.class)) {
        TestAnnotation ta = m.getAnnotation(TestAnnotation.class);
        System.out.println(ta.testText());
    }
}

Not much different for field annotations like yours.

去了角落 2024-10-11 10:05:59

我从来没有这样做过,但它看起来像 字段 是一个 AnnotatedElement 所以它有 getAnnotation此页面有一个示例(复制如下);如果您知道注释的类并且注释策略在运行时保留注释,则非常简单。当然,如果保留策略不在运行时保留注释,您将无法在运行时查询它。

已删除的答案(?)提供了指向注释教程的有用链接 您可能会发现有帮助;我已将链接复制到此处,以便人们可以使用它。

此页面中的示例:

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
  String str();

  int val();
}

class Meta {
  @MyAnno(str = "Two Parameters", val = 19)
  public static void myMeth(String str, int i) {
    Meta ob = new Meta();

    try {
      Class c = ob.getClass();

      Method m = c.getMethod("myMeth", String.class, int.class);

      MyAnno anno = m.getAnnotation(MyAnno.class);

      System.out.println(anno.str() + " " + anno.val());
    } catch (NoSuchMethodException exc) {
      System.out.println("Method Not Found.");
    }
  }

  public static void main(String args[]) {
    myMeth("test", 10);
  }
}

I've never done it, but it looks like Reflection provides this. Field is an AnnotatedElement and so it has getAnnotation. This page has an example (copied below); quite straightforward if you know the class of the annotation and if the annotation policy retains the annotation at runtime. Naturally if the retention policy doesn't keep the annotation at runtime, you won't be able to query it at runtime.

An answer that's since been deleted (?) provided a useful link to an annotations tutorial that you may find helpful; I've copied the link here so people can use it.

Example from this page:

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
  String str();

  int val();
}

class Meta {
  @MyAnno(str = "Two Parameters", val = 19)
  public static void myMeth(String str, int i) {
    Meta ob = new Meta();

    try {
      Class c = ob.getClass();

      Method m = c.getMethod("myMeth", String.class, int.class);

      MyAnno anno = m.getAnnotation(MyAnno.class);

      System.out.println(anno.str() + " " + anno.val());
    } catch (NoSuchMethodException exc) {
      System.out.println("Method Not Found.");
    }
  }

  public static void main(String args[]) {
    myMeth("test", 10);
  }
}
日久见人心 2024-10-11 10:05:59

详细说明@Cephalopod的答案,如果您想要列表中的所有列名称,您可以使用此oneliner:

List<String> columns = 
        Arrays.asList(MyClass.class.getFields())
              .stream()
              .filter(f -> f.getAnnotation(Column.class)!=null)
              .map(f -> f.getAnnotation(Column.class).columnName())
              .collect(Collectors.toList());

Elaborating to the answer of @Cephalopod, if you wanted all column names in a list you could use this oneliner:

List<String> columns = 
        Arrays.asList(MyClass.class.getFields())
              .stream()
              .filter(f -> f.getAnnotation(Column.class)!=null)
              .map(f -> f.getAnnotation(Column.class).columnName())
              .collect(Collectors.toList());
总攻大人 2024-10-11 10:05:59

虽然到目前为止给出的所有答案都完全有效,但人们还应该记住 Google 反射库 一种更通用、更简单的注释扫描方法,例如

 Reflections reflections = new Reflections("my.project.prefix");

 Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);

While all the answers given so far are perfectly valid, one should also keep in mind the google reflections library for a more generic and easy approach to annotation scanning, e.g.

 Reflections reflections = new Reflections("my.project.prefix");

 Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
凡间太子 2024-10-11 10:05:59

通常情况下,您对字段具有私有访问权限,因此您不能在反射中使用getFields。相反,您应该使用 getDeclaredFields

因此,首先,您应该知道您的 Column 注释是否具有运行时保留:

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
}

之后您可以执行以下操作:

for (Field f: MyClass.class.getDeclaredFields()) {
   Column column = f.getAnnotation(Column.class);
       // ...
}

显然,您想对字段执行某些操作- 使用注释值设置新值:

Column annotation = f.getAnnotation(Column.class);
if (annotation != null) {
    new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
        object,
        myCoolProcessing(
            annotation.value()
        )
    );
}

因此,完整代码可以如下所示:

for (Field f : MyClass.class.getDeclaredFields()) {
    Column annotation = f.getAnnotation(Column.class);
    if (annotation != null)
        new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
                object,
                myCoolProcessing(
                        annotation.value()
                )
        );
}

In common case you have private access for fields, so you CAN'T use getFields in reflection. Instead of this you should use getDeclaredFields

So, firstly, you should be aware if your Column annotation has the runtime retention:

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
}

After that you can do something like this:

for (Field f: MyClass.class.getDeclaredFields()) {
   Column column = f.getAnnotation(Column.class);
       // ...
}

Obviously, you would like to do something with field - set new value using annotation value:

Column annotation = f.getAnnotation(Column.class);
if (annotation != null) {
    new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
        object,
        myCoolProcessing(
            annotation.value()
        )
    );
}

So, full code can be looked like this:

for (Field f : MyClass.class.getDeclaredFields()) {
    Column annotation = f.getAnnotation(Column.class);
    if (annotation != null)
        new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
                object,
                myCoolProcessing(
                        annotation.value()
                )
        );
}
萌化 2024-10-11 10:05:59

在我的例子中,您还可以使用泛型类型,考虑到您可以执行以下操作之前所说的所有内容:

public class SomeTypeManager<T> {

    public SomeTypeManager(T someGeneric) {

        //That's how you can achieve all previously said, with generic types.
        Annotation[] an = someGeneric.getClass().getAnnotations();

    }

}

记住,这不会 100% 等于 SomeClass.class.get(...)();

但能做到这一点...

You can also use generic types, in my case, taking into account everything said before you can do something like:

public class SomeTypeManager<T> {

    public SomeTypeManager(T someGeneric) {

        //That's how you can achieve all previously said, with generic types.
        Annotation[] an = someGeneric.getClass().getAnnotations();

    }

}

Remember, that this will not equival at 100% to SomeClass.class.get(...)();

But can do the trick...

东风软 2024-10-11 10:05:59

对于少数要求通用方法的人来说,这应该对您有帮助(5 年后:p)。

对于下面的示例,我从具有 RequestMapping 注释的方法中提取 RequestMapping URL 值。
要适应字段,只需将 RequestMapping 的用法更改

for (Method method: clazz.getMethods())

for (Field field: clazz.getFields())

并交换您要阅读的任何注释。
但请确保注释具有@Retention(RetentionPolicy.RUNTIME)

public static String getRequestMappingUrl(final Class<?> clazz, final String methodName)
{
    // Only continue if the method name is not empty.
    if ((methodName != null) && (methodName.trim().length() > 0))
    {
        RequestMapping tmpRequestMapping;
        String[] tmpValues;

        // Loop over all methods in the class.
        for (Method method: clazz.getMethods())
        {
            // If the current method name matches the expected method name, then keep going.
            if (methodName.equalsIgnoreCase(method.getName()))
            {
                // Try to extract the RequestMapping annotation from the current method.
                tmpRequestMapping = method.getAnnotation(RequestMapping.class);

                // Only continue if the current method has the RequestMapping annotation.
                if (tmpRequestMapping != null)
                {
                    // Extract the values from the RequestMapping annotation.
                    tmpValues = tmpRequestMapping.value();

                    // Only continue if there are values.
                    if ((tmpValues != null) && (tmpValues.length > 0))
                    {
                        // Return the 1st value.
                        return tmpValues[0];
                    }
                }
            }
        }
    }

    // Since no value was returned, log it and return an empty string.
    logger.error("Failed to find RequestMapping annotation value for method: " + methodName);

    return "";
}

For the few people asking for a generic method, this should help you (5 years later :p).

For my below example, I'm pulling the RequestMapping URL value from methods that have the RequestMapping annotation.
To adapt this for fields, just change the

for (Method method: clazz.getMethods())

to

for (Field field: clazz.getFields())

And swap usage of RequestMapping for whatever annotation you are looking to read.
But make sure that the annotation has @Retention(RetentionPolicy.RUNTIME).

public static String getRequestMappingUrl(final Class<?> clazz, final String methodName)
{
    // Only continue if the method name is not empty.
    if ((methodName != null) && (methodName.trim().length() > 0))
    {
        RequestMapping tmpRequestMapping;
        String[] tmpValues;

        // Loop over all methods in the class.
        for (Method method: clazz.getMethods())
        {
            // If the current method name matches the expected method name, then keep going.
            if (methodName.equalsIgnoreCase(method.getName()))
            {
                // Try to extract the RequestMapping annotation from the current method.
                tmpRequestMapping = method.getAnnotation(RequestMapping.class);

                // Only continue if the current method has the RequestMapping annotation.
                if (tmpRequestMapping != null)
                {
                    // Extract the values from the RequestMapping annotation.
                    tmpValues = tmpRequestMapping.value();

                    // Only continue if there are values.
                    if ((tmpValues != null) && (tmpValues.length > 0))
                    {
                        // Return the 1st value.
                        return tmpValues[0];
                    }
                }
            }
        }
    }

    // Since no value was returned, log it and return an empty string.
    logger.error("Failed to find RequestMapping annotation value for method: " + methodName);

    return "";
}
2024-10-11 10:05:59

我使用它的方式之一:

protected List<Field> getFieldsWithJsonView(Class sourceClass, Class jsonViewName){
    List<Field> fields = new ArrayList<>();
    for (Field field : sourceClass.getDeclaredFields()) {
        JsonView jsonViewAnnotation = field.getDeclaredAnnotation(JsonView.class);
        if(jsonViewAnnotation!=null){
            boolean jsonViewPresent = false;
            Class[] viewNames = jsonViewAnnotation.value();
            if(jsonViewName!=null && Arrays.asList(viewNames).contains(jsonViewName) ){
                fields.add(field);
            }
        }
    }
    return fields;
}    

one of the ways I used it :

protected List<Field> getFieldsWithJsonView(Class sourceClass, Class jsonViewName){
    List<Field> fields = new ArrayList<>();
    for (Field field : sourceClass.getDeclaredFields()) {
        JsonView jsonViewAnnotation = field.getDeclaredAnnotation(JsonView.class);
        if(jsonViewAnnotation!=null){
            boolean jsonViewPresent = false;
            Class[] viewNames = jsonViewAnnotation.value();
            if(jsonViewName!=null && Arrays.asList(viewNames).contains(jsonViewName) ){
                fields.add(field);
            }
        }
    }
    return fields;
}    
池予 2024-10-11 10:05:59

要读取 java 中注释的值,请尝试执行以下步骤:

  1. 创建注释。
  2. 遵循下面目标类中的逻辑。
  3. 访问输出中的值。

注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE}) // make annotation usable only for classes
@Retention(RetentionPolicy.RUNTIME) // make annotation available at the runTime
public @interface EntryPoint {
    String url();
}

目标

// just remember to import your annotation in this case "EntryPoint"

import java.lang.annotation.Annotation;

@EntryPoint(url = "api/v1/demo")
public class Demo {
    // get class of this.
    private final Class<? extends Demo> demo = this.getClass();
    // get specific annotation (EntryPoint.class)
    private final Annotation annotation = demo.getAnnotation(EntryPoint.class);
    // instantiate annotation and assign it value from the class annotation.
    final EntryPoint entryPoint = (EntryPoint) annotation;
}

输出

public class Main {
    public static void main(String[] args) {
        // create an object of the class with the annotation.
        Demo demo = new Demo();
        System.out.println(demo.entryPoint.url());
    }
}

结果为“api/v1/demo”

To read the value of annotation in java try to follow the following steps:

  1. Create an annotation.
  2. Follow the logic in the target class below.
  3. Access the value as in Output.

Annotation

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE}) // make annotation usable only for classes
@Retention(RetentionPolicy.RUNTIME) // make annotation available at the runTime
public @interface EntryPoint {
    String url();
}

Target

// just remember to import your annotation in this case "EntryPoint"

import java.lang.annotation.Annotation;

@EntryPoint(url = "api/v1/demo")
public class Demo {
    // get class of this.
    private final Class<? extends Demo> demo = this.getClass();
    // get specific annotation (EntryPoint.class)
    private final Annotation annotation = demo.getAnnotation(EntryPoint.class);
    // instantiate annotation and assign it value from the class annotation.
    final EntryPoint entryPoint = (EntryPoint) annotation;
}

Output

public class Main {
    public static void main(String[] args) {
        // create an object of the class with the annotation.
        Demo demo = new Demo();
        System.out.println(demo.entryPoint.url());
    }
}

The result is "api/v1/demo"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文