In short, no. Java does not support this.
You can build something like this, noting that you define aliases per instance, not on the class itself. Modify as needed:
public class AliasThingy {
private final Map<String, Object> storage = new HashMap<>();
private final Map<String, String> aliases = new HashMap<>();
public AliasThingy (Map<String, List<String>> aliases) {
aliases.forEach((key, value) -> value.forEach(alias -> this.aliases.put(alias, key)));
}
public void set(String key, Object value) {
storage.put(aliases.getOrDefault(key, key), value);
}
public <T> T get(String key) {
return (T)storage.get(aliases.getOrDefault(key, key));
}
public static void main(String[] args) {
var something = new AliasThingy(Map.of(
"id", List.of("somethingId")
));
something.set("id", 1L);
assert((long)something.get("somethingId") == 1L);
something.set("somethingId", 2L);
assert((long)something.get("id") == 2L);
}
}
You could also use it as a base class, which lets you define the aliases in the class definition, plus an opportunity to avoid raw strings:
public class Something extends AliasThingy {
public interface KEYS {
String ID = "id";
String SOMETHING_ID = "somethingId";
String NAME = "name";
String DESCRIPTION = "description";
String TITLE = "title";
}
public Something() {
super(Map.of(
KEYS.ID, List.of(KEYS.SOMETHING_ID),
KEYS.NAME, List.of(KEYS.DESCRIPTION, KEYS.TITLE)
));
}
public static void main(String[] args) {
Something something = new Something();
something.set(KEYS.ID, 1L);
assert((long)something.get(KEYS.SOMETHING_ID) == 1L);
something.set(KEYS.SOMETHING_ID, 2L);
assert((long)something.get(KEYS.ID) == 2L);
something.set(KEYS.TITLE, "Dr. Strangelove");
assert(something.get(KEYS.NAME).equals("Dr. Strangelove"));
assert(something.get(KEYS.DESCRIPTION).equals("Dr. Strangelove"));
}
}