Proposal: Concise declaration of JavaBeans properties
Jan Kroken
jan.kroken at gmail.com
Thu Jun 25 03:36:01 PDT 2009
PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0
AUTHOR(S): Jan Kroken
OVERVIEW
Add syntactic sugar to reduce the amount of boilerplate code needed
to adhere to the JavaBeans specification.
FEATURE SUMMARY: Should be suitable as a summary in a language tutorial.
Add a new field modifier, that will generate the neccessary JavaBeans
methods at compile time.
MAJOR ADVANTAGE:
Significantly reduce the amount of boilerplate code in Java source code.
MAJOR BENEFIT:
Reducing the amount of boilerplate code will:
- increase readability
- reduce the amount of possible programming errors
- reduce implementation and maintenance cost
MAJOR DISADVANTAGE:
The proposal will increase the complexity of the language. Methods will
exist without having an explicit declaration, which may confuse
programmers
not familiar with the feature.
ALTERNATIVES:
The same feature can possibly be implemented using annotations and
runtime code generation.
EXAMPLES
SIMPLE EXAMPLE:
A value class in the current java language:
public class MyValueObject {
private Type1 field1;
private Type2 field2;
public void setField1(Type1 field1) {
this.field1 = field1;
}
public Type1 getField1() {
return field1;
}
public Type2 getField2() {
return field2;
}
}
The same value with the proposed language modification
public class MyValueObject {
private :exposed(rw) Type1 field1;
private :exposed(r) Type2 field2;
}
Note that :exposed is not the suggested syntax modification.
The exact notation should be decided upon by the working group.
In the above example, :exposed(rw) will expose the value both
through a getter and setter, while :exposed(r) will expose the
value only through a getter.
ADVANCED EXAMPLE:
Any explicit declarations of a JavaBeans method in the current class
will ensure that the method is not generated based on the field
declaration.
For instance, the class
public class MyValueObject {
private :exposed(rw) Type1 field1;
private :exposed(r) Type2 field2;
public void setField1(Type1 field1) {
if(field1 == null) {
throw new NullPointerException();
}
this.field1 = field1;
}
}
will be equivalent to
public class MyValueObject {
private Type1 field1;
private Type2 field2;
public void setField1(Type1 field1) {
if(field1 == null) {
throw new NullPointerException();
}
this.field1 = field1;
}
public Type1 getField1() {
return field1;
}
public Type2 getField2() {
return field2;
}
}
DETAILS
SPECIFICATION:
A modifier, currently represented by :exposed(specification),
should be added to class fields.
The modifier has two optional arguments, r (read) and w (write).
a read argument specifies that the compiler should generate
public JavaBeans read methods for the field. The write argument
specifies that the compiler should generate a public JavaBeans
set method for the field.
If the field is a boolean field, both a getField and a isField
method will be generated. If one of those are declared in the
current class, none will be generated. This is to avoid a loophole
where a transformation is added to one of those, while the field
is accidentally made available through the other.
if no arguments are provided, both read and write methods will
be generated.
Any explicit declarations of a JavaBeans method in the current class
will ensure that the method is not generated based on the field
declaration.
If a field is declared as an exposed, and there is a conflict with
JavaBeans methods implemented in a superclass, the JavaBeans methods
will be generated, and override the ones declared in the superclass.
The added field modifier should be chosen so it does not conflict
with any existing Java source code.
The change would be implemented as desugaring at compile time. The
class file format or type system will not be affected.
The effect this change will have on stack trace information and
debugging information has not been analyzed.
TESTING:
It will be possible to create test code with a full coverage of all
variants.
LIBRARY SUPPORT:
There is no need for library support.
REFLECTIVE APIS:
This change will not require changes to the reflection apis.
OTHER CHANGES:
The only component that needs to be modified is the compiler.
MIGRATION: Sketch how a code base could be converted, manually or
automatically, to use the new feature.
A class could be modified through a series of transformations:
if there is a setter that matches the JavaBeans specification for a
field, and the setter does not contain any other operations than
assigning
the field to the passed arguemnt, then the setter can be removed, and
the modifier :exposed(w) be added to the field declaration.
if there is a getter that matches the JavaBeans specification, the
getter
only returns the field value without performing any other operations,
and
there is not another getter not complying with these criteria, the
getter(s) can be removed, and the modifier :exposed(r) be added to the
field declaration.
redundant occurences of :exposed(r) or :exposed(w) in one field
declaration should be removed.
If a field declaration has both an :exposed(r) and an :exposed(w)
modifier, both should be removed and replaced with a modifier
:exposed.
COMPATIBILITY
BREAKING CHANGES:
No existing java programs will break. However, parsers, compilers and
source analyzing applications for the java language will break, and have
to be modified.
EXISTING PROGRAMS:
There will be no changes in behaviour for existing programs, neither
class files nor programs compiled from source.
REFERENCES
EXISTING BUGS:
URL FOR PROTOTYPE (optional):
No prototype at this time.
More information about the coin-dev
mailing list