PROPOSAL: @OverrideAll annotation (original) (raw)

Gabriel Belingueres belingueres at gmail.com
Tue Mar 31 07:15:01 PDT 2009


Yes.

I thought this for easily implementing Null objects, because it has such a direct relationship with inheritance, and because they usually don't do much.

I suppose the idea could be extended to support delegation too (as is the case with the Proxy pattern.) That would be nice.

2009/3/31, rssh at gradsoft.com.ua <rssh at gradsoft.com.ua>:

> Hi, > > I've written a new feature that might be comfortable to use for > someone. All input is welcomed. >

It-is possible to do near same with annotation API (create a superclass which will override all) But -- sometime we really need to say, that all methods 'mus be' overriden. (For example - when implementing Proxy pattern). In such case class-level annotation '@OverrideAll' which tell compiler to check, that all methods must be overriden -- brilliant idea.

> 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. > >



More information about the coin-dev mailing list