Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以在java中读取注释的值吗?_Java_Annotations_Getter Setter_Java 6 - Fatal编程技术网

可以在java中读取注释的值吗?

可以在java中读取注释的值吗?,java,annotations,getter-setter,java-6,Java,Annotations,Getter Setter,Java 6,这是我的代码: @Column(columnName="firstname") private String firstName; @Column(columnName="lastname") private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = f

这是我的代码:

@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”)的值吗?

我从未这样做过,但它似乎提供了这一功能。这是一个很好的例子。有一个例子(复制如下);如果您知道注释的类,并且注释策略在运行时保留注释,则非常简单。当然,如果保留策略在运行时不保留注释,您将无法在运行时查询它

一个已经被删除的答案(?)提供了一个有用的链接,你可能会发现它很有用;我在这里复制了链接,以便人们可以使用它

示例来自:


是,如果列批注具有运行时保留期

@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()

当然是。以下是一个示例注释:

@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());
    }
}
对于像您这样的字段注释没有太大的不同


干杯

虽然到目前为止给出的所有答案都是完全有效的,但我们也应该记住一个更通用、更简单的注释扫描方法,例如

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

 Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
Reflections=newreflections(“my.project.prefix”);
设置Id=reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);

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

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();

    }

}
公共类SomeTypeManager{
公共SomeTypeManager(T someGeneric){
//这就是如何使用泛型类型实现前面提到的所有功能。
注释[]an=someGeneric.getClass().getAnnotations();
}
}
记住,这不会100%等同于SomeClass.class.get(…)()


但是可以做到这一点…

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

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());
列表列=
Arrays.asList(MyClass.class.getFields())
.stream()
.filter(f->f.getAnnotation(Column.class)!=null)
.map(f->f.getAnnotation(Column.class).columnName())
.collect(Collectors.toList());

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

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

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
}
之后,您可以执行以下操作:

for (Field f: MyClass.class.getDeclaredFields()) {
   Column column = f.getAnnotation(Column.class);
       // ...
}
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()
                )
        );
}
显然,您希望使用注释值对字段设置新值进行一些操作:

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 column = f.getAnnotation(Column.class);
       // ...
}
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()
                )
        );
}

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

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

for (Method method: clazz.getMethods())

并将RequestMapping的用法替换为您希望阅读的任何注释。 但请确保批注具有@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 "";
}
public静态字符串getRequestMappingUrl(最终类clazz,最终字符串methodName)
{
//仅当方法名称不为空时才继续。
如果((methodName!=null)&&(methodName.trim().length()>0))
{
请求映射tmpRequestMapping;
字符串[]tmpValues;
//循环类中的所有方法。
for(方法:clazz.getMethods())
{
//如果当前方法名与预期的方法名匹配,则继续。
if(methodName.equalsIgnoreCase(method.getName()))
{
//尝试从当前方法提取RequestMapping注释。
tmpRequestMapping=method.getAnnotation(RequestMapping.class);
//仅当当前方法具有RequestMapping注释时才继续。
if(tmpRequestMapping!=null)
{
//从RequestMapping注释中提取值。
tmpValues=tmpRequestMapping.value();
//仅当存在值时才继续。
如果((tmpValues!=null)&&(tmpValues.length>0))
{
//返回第一个值。
返回tmpValues[0];
}
}
}
}
}
//由于未返回任何值,请记录该值并返回空字符串。
logger.error(“未能找到方法“+methodName”的RequestMapping注释值);
返回“”;
}

我使用它的方法之一:

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;
}    
受保护列表getFieldsWithJsonView(类sourceClass,类jsonViewName){
列表字段=新的ArrayList();
for(字段:sourceClass.getDeclaredFields()){
JsonView jsonViewAnnotation=field.getDeclaredAnnotation(JsonView.class);
if(jsonViewAnnotation!=null){
布尔值jsonViewPresent=false;
类[]viewNames=jsonViewAnnotation.value();
if(jsonViewName!=null&&Arrays.asList(viewNames.contains)(jsonViewName)){
字段。添加(字段);
}
}
}
返回字段;
}    

我喜欢你的解决方案。我们如何使它更通用,而不是我想要使用T like(字段f:T.class.getFields()){Column Column=f.getAnnotation(Column.class);if(Column!=null)System.out.println(Column.columnName());}的MyClass!我也一直在努力弄明白这一点。如果我想要一个不需要显式提供类名的注释处理器,该怎么办?可以从上下文中提取它吗我不知道你们两个需要什么。请把这个问题作为一个新问题提出来