获取有关实例变量名称的setter信息

时间:2015-03-13 09:13:13

标签: java

是否可以在对象的setter中获取当前实例的变量名?

像这样的东西

public class Class {
    private DataType dataType;
}

public class DataType {

    public void setValue(String value) {
        if (variableName is 'dataType') {
            this.value = value;
        } else {
            this.value = null;
        }
    }
}

如果使用标准实用程序无法实现,那么可以创建某种注释来存储变量名称,然后在setter中使用它吗?

当我尝试这样做时 - 注释为空。 我创建了注释

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface FieldName {

    String fieldName();
}

然后我将它添加到字段

public class Class {
    @FieldName(fieldName = "dataType")
    private DataType dataType;
}

当我尝试在getter的{​​{1}}中获取它时,注释DataType为空。

FieldName

2 个答案:

答案 0 :(得分:1)

您尝试做的事情有一些问题:

  1. 您的RetentionPolicy被设置为CLASS,这意味着类加载器将丢弃它,并且在运行时将无法使用它。您应该使用RetentionPolicy.RUNTIME代替。

  2. this.getClass().getAnnotation(FieldName.class)会为您提供课程注释。

  3. 在下面的示例中,注释不为null,您可以在"example"方法中获取setValue字符串:

    @FieldName(fieldName = "example")
    public class DataType {
    
        public void setValue(String value) {
            System.out.println(this.getClass().getAnnotation(FieldName.class));
        }
    
    }
    
    public static void main(String[] args) {
        new DataType().setValue("ignored");
    }
    

    这还需要将注释的目标更改为@Target(ElementType.TYPE)

    1. 变量或字段名称只是一个引用,它指向内存中的某个对象。您可以对同一对象进行多次引用。虽然你可以注释不同类中的字段,但是局部变量和参数会出现问题 - 很难说,因为我不知道你想要实现什么。
    2. 有问题的例子:

      public class ClassOne {
          @FieldName(fieldName = "dataType")
          private DataType a;
      }
      
      public class ClassTwo {
          @FieldName(fieldName = "dataType")
          private DataType b;
      }
      
      public class ClassThree {
          public void doSomething() {
              DataType c = new DataType();
          }
      }
      
      public class ClassFour {
          public void doSomething(DataType d) {
              // ...
          }
      }
      

      通常,这都归结为类的实例没有关于如何引用它的信息的问题。但是,对于该字段,封闭类具有此信息。考虑将您的方法移动到该类中。你可以在没有任何注释的情况下处理这个问题:

      public class DataType {
          public void setValue(String value) {
              // ...
          }
      }
      
      public class ClassOne {
          private DataType dataType;
      
          public void setDataTypeValue(String value) {
              dataType.setValue(value);
          }
      }
      
      public class ClassTwo {
          private DataType anyOtherFieldName;
      
          public void setDataTypeValue(String value) {
              anyOtherFieldName.setValue(null);
          }
      }
      

      设置null并忽略参数的setter非常容易引起误解,你的IDE应该给你一个关于未使用参数的警告,这不是没有理由的。我认为你应该考虑重新设计,但我不能在不知道更多细节的情况下进一步建议你。

      尝试解决问题的原因,而不是解决问题。

答案 1 :(得分:0)

使用@Retention(RetentionPolicy.RUNTIME)

替换此

FieldName fieldNameAnnotation = field.getAnnotation(FieldName.class);

有了这个

Field field = this.getClass().getField("dataType");
FieldName fieldName = field.getAnnotation(FieldName.class);