Java 获取有关实例变量名的内部setter信息

Java 获取有关实例变量名的内部setter信息,java,Java,是否可以在对象的setter中获取当前实例的变量名 像这样的 public class Class { private DataType dataType; } public class DataType { public void setValue(String value) { if (variableName is 'dataType') { this.value = value; } else {

是否可以在对象的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;
}
当我试图在
DataType
getter
中获取它时,注释
FieldName
为空

private String wrapGetter(String requiredFieldName, String dataTypeField) {
    FieldName fieldName = this.getClass().getAnnotation(FieldName.class);
    if (fieldName.fieldName().equals(requiredFieldName)) {
        return dataTypeField;
    } else {
        return dataTypeField;
    }
}

您尝试执行的操作存在一些问题:

  • 您的
    RetentionPolicy
    将其设置为
    CLASS
    ,这意味着类加载器将放弃它,并且在运行时它将不可用。您应该改用
    RetentionPolicy.RUNTIME

  • this.getClass().getAnnotation(FieldName.class)
    将为您提供类注释

  • 在下面的示例中,注释不为空,您可以在
    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)

  • 变量或字段名只是一个引用,它指向内存中的某个对象。可以对同一对象有多个引用。虽然您可以在不同的类中注释字段,但局部变量和参数将是一个问题——这很难说,因为我不知道您想要实现什么
  • 有问题的例子:

    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应该就未使用的参数向您发出警告,这不是没有原因的。我认为你应该考虑重新设计,但是我不能在不知道更多细节的情况下进一步建议你。 不要解决问题,而是尝试解决问题的原因。

    使用
    @Retention(RetentionPolicy.RUNTIME)

    替换这个

    FieldName fieldNameAnnotation = field.getAnnotation(FieldName.class);
    
    用这个

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

    变量名可能重复?@SMA嗯……更准确地说,我指的是字段名-
    dataType