1

Is it possible to get the variable name of the current instance in the object's setter?

Something like this

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;
        }
    }
}

If it's not possible using standard utilities then it's possible to create some kind of annotation to store there variable name and then use it in setter?

When I try to do like this - the annotation is null. I create annotation

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

    String fieldName();
}

Then I add it to field

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

And when I try to get it in the getter of DataType - the annotation FieldName is null.

private String wrapGetter(String requiredFieldName, String dataTypeField) {
    FieldName fieldName = this.getClass().getAnnotation(FieldName.class);
    if (fieldName.fieldName().equals(requiredFieldName)) {
        return dataTypeField;
    } else {
        return dataTypeField;
    }
}
lapots
  • 12,553
  • 32
  • 121
  • 242

2 Answers2

1

There are a few problems with what you are trying to do:

  1. Your RetentionPolicy is set it to CLASS which means that class loader will discard it and it will not be available at runtime. You should use RetentionPolicy.RUNTIME instead.

  2. this.getClass().getAnnotation(FieldName.class) will give you the class annotation.

In the below example the annotation is not null and you can get "example" string in setValue method:

@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");
}

This also requires to change the target of your annotation to @Target(ElementType.TYPE).

  1. Variable or field name is just a reference, it points to some object in the memory. You can have multiple references to the same object. Although you can annotate fields in different classes, it will be a problem with local variables and parameters - it is difficult to say as I don't know what you are trying to achieve.

Problematic example:

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) {
        // ...
    }
}

Generally, it all comes down to the problem that the instance of the class has no information about how it is being referred to. However, for the field, enclosing class has this information. Consider moving your method into that class. And you can handle this without any annotations:

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

The setter that sets null and ignores the parameter is very misleading, your IDE should be giving you a warning about unused parameter, it's not without a reason. I think you should consider a redesign, but I cannot advice you further without knowing more details.

Instead of solving the problem, try to solve the cause of that problem.

Jaroslaw Pawlak
  • 5,538
  • 7
  • 30
  • 57
0

Use @Retention(RetentionPolicy.RUNTIME)

Replace this

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

With this

Field field = this.getClass().getField("dataType");
FieldName fieldName = field.getAnnotation(FieldName.class);
muasif80
  • 5,586
  • 4
  • 32
  • 45