PROPOSAL: @OverrideAll annotation (original) (raw)
Gabriel Belingueres belingueres at gmail.com
Tue Mar 31 06:49:20 PDT 2009
- Previous message: Fwd: Proposal: Type inference for variable definition/initialization using the 'auto' keyword.
- Next message: PROPOSAL: @OverrideAll annotation
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi,
I've written a new feature that might be comfortable to use for someone. All input is welcomed.
Regards, Gabriel
PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0
AUTHOR(S): Gabriel Belingueres
OVERVIEW
Add an @OverrideAll annotation to allow a class to override all inherited methods with a trivial implementation. The resulting class then could be used as the basis for a Null Object pattern (or even a basic Mock object.)
FEATURE SUMMARY:
The proposed @OverrideAll annotation will allow the class to override all methods (from its superclasses and implemented interfaces) with a trivial body, but the defined class can choose to implement specific methods, replacing those that would be produced automatically by the annotation.
MAJOR ADVANTAGE:
Less coding for implementing Null Objects, or simple tests.
MAJOR BENEFIT:
Let the compiler implement all uninteresting, non relevant behavior by automatically providing with a trivial implementation of the inherited methods.
MAJOR DISADVANTAGE:
Might be a cause of NullPointerException if not used judiciously.
ALTERNATIVES:
Implement all uninteresting methods by yourself by providing yourself a trivial implementation (though actually popular IDEs can do this automatically for you already.)
EXAMPLES
Given:
class B {}
public class A implements I1, I2 {
public static final int VAR = 1;
private B b;
public static Integer getSome() { return VAR; }
public A() { }
public A(B b) { this.b=b; }
public B getB() { return b; }
public void setB(B b) { this.b=b; }
protected void doProtected() { ... }
private void doPrivate() { ... }
A someNewA() { ... }
public synchronized void someSynchronized() { }
}
then:
@OverrideAll public class NullA extends A { }
is equivalent to declare:
public class NullA extends A {
public NullA() {}
public NullA(B b) { super(b); }
public B getB() { return null; }
public void setB(B b) { }
protected void doProtected() { // empty }
A someNewA() { return null; }
public synchronized void someSynchronized() { // empty }
}
You may not want the default trivial implementation in some methods, then you override them as usual:
@OverrideAll public class NullA extends A {
@Override public B getB() { return new B(); }
@Override public synchronized void someSynchronized() { System.out.println("overridden"); }
}
EXAMPLE 2
Implement a trivial Collection interface just to test that adding elements will increase the collection size:
Currently:
public class SomeCollection implements Collection {
private int counter;
@Override public boolean add(E arg0) { counter++; return true; }
@Override public boolean addAll(Collection<? extends E> c) { counter += c.size(); return true; }
@Override public void clear() { }
@Override public boolean contains(Object arg0) { return false; }
@Override public boolean containsAll(Collection<?> arg0) { return false; }
@Override public boolean isEmpty() { return false; }
@Override public Iterator iterator() { return null; }
@Override public boolean remove(Object arg0) { return false; }
@Override public boolean removeAll(Collection<?> arg0) { return false; }
@Override public boolean retainAll(Collection<?> arg0) { return false; }
@Override public int size() { return counter; }
@Override public Object[] toArray() { return null; }
@Override public T[] toArray(T[] arg0) { return null; }
}
With the annotation:
@OverrideAll public class SomeCollection implements Collection {
private int counter;
@Override public boolean add(E arg0) { counter++; return true; }
@Override public boolean addAll(Collection<? extends E> c) { counter += c.size(); return true; }
@Override public int size() { return counter; }
}
DETAILS
SPECIFICATION:
A preliminary specification follows:
As this feature is proposed as an annotation for code generation, no changes to the current JLSv3 are needed.
The annotation will generate "trivial" overridden implementations for all methods not specified in the class, for each superclass in the hierarchy (except Object) and implemented interface.
Static methods, private methods, final methods, constructors and methods from class Object should never be generated.
If some superclass (except Object) has already overridden some Object class methods, then do NOT generate an empty overridden method (to reuse current behavior.) (for example, if some superclass already override toString(), equals() or hashCode().)
OPTIONAL: add a parameter to the @OverrideAll annotation to indicate if @Deprecated methods should not be implemented.
Trivial implementation for generated methods:
- Methods returning void will have an empty body. (OPTIONAL: add a parameter to the @OverrideAll annotation to indicate that it should throw UnsupportedOperationException instead)
- Methods returning a primitive type will have a body returning the same default value that would have for uninitialized instance variables. (JLS section 4.12.5.)
- Methods returning a reference type will "return null;". (JLS section 4.12.5.)
- The method will never return a covariant return type (because in case of implementing a Null object, it should be undistinguished from the common case)
- Methods that throws checked exceptions can be modified to delete the throws clause. (ie. the trivial implementation should not throw checked exceptions)
- Synchronized methods should retain that attribute.
COMPILATION:
Compilation should proceed as usual, except that the annotation processor would generate the code when it encounters an annotated class.
No changes to the class file format are needed.
TESTING
Test cases should be done, including testing with classes implementing several interfaces, classes with generics, inner classes, etc.
LIBRARY SUPPORT:
No, except creating the new annotation.
REFLECTIVE APIS:
No changes foreseen.
OTHER CHANGES:
Output of javadoc tool.
MIGRATION:
Just add the annotation to class level, and erase your trivially implemented overridden methods.
COMPATIBILITY
BREAKING CHANGES: All existing programs remain valid.
EXISTING PROGRAMS: The semantics of existing class files and legal source files are unchanged by this feature.
REFERENCES
EXISTING BUGS:
None that I know about.
URL FOR PROTOTYPE:
None at this time.
- Previous message: Fwd: Proposal: Type inference for variable definition/initialization using the 'auto' keyword.
- Next message: PROPOSAL: @OverrideAll annotation
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]