0

In Java you can write:

System.out.println(Abc.class.getName());

It will always print the correct value, even if the class Abc is moved or renamed.

What is the closest you can get to that for field names?

In other words, what can I code that will always give me the "current" name of a field in a class, even if that field is renamed. Ideally, it would also fail to compile if the field is removed altogether. Or at least fail as soon as the class is accessed, during static initialisation.

I want this to simplify a "change tracking" system. It's not quite like "bean properties", because those names are NOT visible outside the class itself.

AFAIK, there is no "native" way to do this, but I'm hoping there might be some trick with annotations and/or reflection that does the job.

I'll write what I'm doing now (minimally simplified):

private static final String IS_SWAPPABLE = "isSwappable";
// ...
private boolean isSwappable;
// ...
public boolean isSwappable() {
    if ((clientChanges != null) &&
                  clientChanges.containsKey(IS_SWAPPABLE)) {
        return (Boolean) clientChanges.get(IS_SWAPPABLE);
    }
    return isSwappable;
}

public boolean setSwappable(final boolean newSwappable) {
    if (isSwappable() != newSwappable) {
        isSwappable = newSwappable;
        onFieldChange(IS_SWAPPABLE, newSwappable);
        return true;
    }
    return false;
}

What I would like is some "magic" that sets the value of IS_SWAPPABLE to "isSwappable" such that if isSwappable is renamed, then IS_SWAPPABLE will be updated appropriately.

OTOH, if there was a syntax like Abc.isSwappable (or Abc#isSwappable) or whatever, I would spare myself the constant, and just write that directly.

What I can do atm is (once) go over the constants (by using some clear naming convention), and make sure for each of them there is an instance field with the same name. But it doesn't really guaranties that IS_SWAPPABLE is used where isSwappable is used.

Sebastien Diot
  • 7,183
  • 6
  • 43
  • 85
  • 1
    http://stackoverflow.com/questions/13554583/is-it-possible-to-reflect-a-java-method-statically – Sotirios Delimanolis Jun 07 '16 at 15:30
  • 1
    [why MyClass.class exists in java and MyField.field isn't?](http://stackoverflow.com/questions/4485875/why-myclass-class-exists-in-java-and-myfield-field-isnt) – Sotirios Delimanolis Jun 07 '16 at 15:31
  • ' even if the class Abc is moved or renamed.' In what sense? If you remove the class Abc then your program will neither compile nor be able to run! – Michal Jun 07 '16 at 15:37
  • For me the best you can do if the name is not a valid criteria to find a field for you, it could be the type/generic type of the field. You know (thx to a custom annotation?) that this class has 3 fields of type X, 2 fields of type Y... then you check that if it is still the case if not it fails, is it what you are looking for? – Nicolas Filotto Jun 07 '16 at 15:49
  • @Michal We are using an *IDE* ... :D All references will be updated automatically when refactoring, so the program will still compile and work (unless there are "external references" to that class, in the DB or whatever). – Sebastien Diot Jun 07 '16 at 16:49
  • @Sebastien: Sorry, you wrote renamed and I read removed. My mistake. – Michal Jun 08 '16 at 13:08
  • 1
    @Sebastien: In that case I guess the closest thing I can imagine for your requirement is something similar to JPA Static Metamodel Generator. It does not neccessarily handle rename or move automatically but at the very least you get a compiler error when something has changed and needs to be updated. – Michal Jun 08 '16 at 13:09

1 Answers1

-1

It looks very simple.

    for (Field field : getClass().getFields()) {
        System.out.println(field.getName());
    }

Then you can mark fields with your own annotations and then read their values like this

    for (Field field : getClass().getFields()) {
        System.out.println(field.getName());
        MyAnnotation annotation = field.getAnnotation( MyAnnotation.class );
        System.out.println(annotation.value());
    }
Mikhail Kopylov
  • 2,008
  • 5
  • 27
  • 58
  • I think you're misunderstanding their question. – Sotirios Delimanolis Jun 07 '16 at 15:47
  • He wants to get straight access to field. As there's no such one I suggest a workaround. – Mikhail Kopylov Jun 07 '16 at 16:15
  • I don't see how this is useful to me. I don't want the name of all fields, but rather the name of a specific field. If I have a field "age", I want to use the "name" of that field in the getter and setter of that field. Of course, I can get the name of all fields anywhere in the code, but I won't know which of those is the field I am accessing in the actual getter/setter. Atm, I am just typing the name as a string, but if someone refactor the code, the string will not match the real field name. – Sebastien Diot Jun 07 '16 at 16:45
  • Ok may be I don't get the question in correct. Could you provide a pseudo code example please? – Mikhail Kopylov Jun 07 '16 at 16:49