PROPOSAL: @OverrideAll annotation

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<E> implements Collection<E> {
> >
> >   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<E> 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> T[] toArray(T[] arg0) {
> >     return null;
> >   }
> >
> > }
> >
> > With the annotation:
> >
> > @OverrideAll
> > public class SomeCollection<E> implements Collection<E> {
> >
> >   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