The Getter, the Setter and the Property
July 2nd, 2006Remember http://www.javalobby.org/java/forums/t74270.html?start=0? It seems that everybody read and replied on it:-)
Nearly all proposals made (even the one I added my self) have a serious problem: They don’t play well with interfaces.
First I like to define what I mean when I talk about a Property:
A Property is a member where get().equals(get()) and set(x) => get().equals(x).
The java.util.Properties fulfill this condition nicely, as do simple members like names, etc. The Properties-class was actually what got me the idea: As I was faced at work of writing hundreds of getter/setter and member declarations, I took a short-cut and handled this by named attributes. The only thing we lost (besides some CPU-cycles) was type-safety (not a concern in the situation) and the clear binding that allowed refactoring (important then, no issue now). Most of non-trivial get/set are actually interceptors that don’t modify the behaviour from a simple member access. If this is not true you don’t a have Property in the sense of this text.
Why the concept of properties at all? Because it carries important semantics. The user of a property is encouraged to rely on this, this will simplfy code and makes programm more stable if the rule can be checked by an “meta-assert”.
So general advice, if “dynamic” properties will do: Go for it, especially in web-programming where you can spit out String for numbers and dates.
Well, I admit that this is not too satisfying, so here a better solution, but it’ll require a JSR:
The property keyword
The keyword property is somewhat similar in it use as the enum keyword.
property { An anonymous property can only be used as an inner property
int a,
String b,
HashMap m
}
class MyClass{ This will allow to write myClass.a=”Donkey” and String s = myClass.a, as 2==myClass.a (Actually I propose set() to return the new value value so that int x = myClass.a=4; works as expected)
public property {
String a get() { if (a==null) a=getInitialValue(); return a;} set(String s){ assert s!=null; a=s;},
int a
}
Properties can be extended in the usual fashion and they behave like the java.util.Properties then.Named properties can be used like an interface, thus they must not contain implementations for get/set:
public property MyProps{
int a, int z
}
class MyClass implements MyProps
will have synthetic attributes a and z both public. As these are synthetic attributes they can be intercepted by
@Override int a get(){return 0};Multiple sets of properties can be used in a class:
public property aSet extends MyProps {/*additional fields and interceptors go here*/};
public property anotherSet extends MyProps {/*additional fields and interceptors go here*/};
to make myClass.aSet.a=myClass.anotherSet.z a legal assignment.
So what did we get?
- A new semantical construct that transfers more information on the behaviour than a setter/getter-pair
- A simple, lean syntax for manipulating fields
- AOP-like features on fields
- Interfaces that declare fields without the problems of multiple inheritance
I feel that this is already enough, as well I see also the advantage that we provide something similar what C# has - to make C#-programmer switch over or more importantly to enable programmers to work with both languages more easily.
Advanced issues
Limiting visibility must follow the same rules as for classes/interfaces, as the synthetic field should behave like accessor function-pairs.
The property should allow to override the generic accessor mechanism by defining
get(String name) and set(String name, T value)
ReadOnly properties are useful in some cases, this could be either achieved by phony setters (see above) or by splitting property declaration (which would remove most of the ease of use)
Volatile and transient properties must be supported, their behaviour must be transparent because the programmer should not need to distinguish between true fields and properties.
A final property is a property that disallows the override of any accessor, it is not final in the sense of a field being final.
A simplyfied declaration for the get/set could be considered:
int a get{} set{assert a!=this.a; this.a=a}...
Highly advanced (I think too dangerous): Implicit conversions:
int a String get() {return String.valueOf(a)} String set(String s) { a=Integer.parseInt(s);return a;}
So what do you think?
Is this an idea worth creating an JSR? Do you see corners where this might break something? Ii is not perfect yet, it requires some work for sure - Participate!

July 2nd, 2006 at 3:35 pm
Why all this effort on something so minor? My IDE generates getters and setters for me. Once they are created, I never look at them unless I need to make one do something special. This is such a minor problem. I don’t know why a small group of very vocal people keep saying this is terrible. There is nothing wrong with Java in this respect.
July 3rd, 2006 at 9:05 am
Delphi and C++ Builder supported this feature eons before java. The feature was dropped by the creators of Java because it was error prone. You will never again know when a certain code snippet is simple attribute assignment or a complex method call. This is not theoretical, but real concerns when working with both environments.
If you ask, I do not want to go back to those days when I didn’t know the meaning of the code I was reading without going back and forth. If there is a method call, I want that to be expressed in code. Aspects are a legal exception because I can find them easily and comply with the One Responsibility Rule.