The Source for Java Technology Collaboration

Home » java.net Forums » JDK » Java SE

Thread: Generic "this" ("self") method return type

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 4 - Last Post: May 4, 2006 7:20 AM by: kfgodel
peterkehl

Posts: 4
Generic "this" ("self") method return type
Posted: Jan 28, 2005 10:45 AM
  Click to reply to this thread Reply

Could we have way of declaring method return type to be its current (mplementation) subclass. Then calls on subclass instance could be easily chained.

Current way is to have override a method with its current class as return type. It calls parent method, and then returns this :

class Base {
  protected final void setDo( Object key, Object value ) { /*do-what-told*/ }
  public Base set( Object key, Object value ) { setDo( old, value ); return this; }
}
 
class Child extends Base {
  public Child set( Object key, Object value ) { setDo( key, value ); return this; }
 
  protected final void setSeveral( Map pairs ) {
    for( final Map.Entry entry : pairs.entrySet() ) {
      set( entry.getKey(), entry.getValue() );
    }
  }
 
  public Child setSeveral( Map pairs ) {
    setDo( pairs );
    return this;
  }
}


This allows subclass to have new methods added, while both inherited and own methods can be called in chain (like StringBuffer):

new Child().set( "name", "Happy" ).set( mapOfKeyValuePairsToSet ).set( "description", "Friend" );


However, that makes subclasses have non-creative Xyz(...)methods, which just:
1. narrow down return type, so that chained calls to own methods are possible
2. call parent XyzDo(...) method
3. return this

That makes subclasses:
1. awkward
2. pottentially out-of-contract, because child method can process additional/different code that just calling parent method and returning this

Above could be healed if there were a possibility to defined method return type to be "generic this", ie its current implementation class type. If we use <~> notation here, it would look like:

class Base {
  public final <~> set( Object key, Object value ) {
    /*do-what-told*/
    return this;
  }
}
 
class Child extends Base {
  public final <~> setSeveral( Map pairs ) {
    for( final Map.Entry entry : pairs.entrySet() ) {
      set( entry.getKey(), entry.getValue() );
    }
    return this;
  }
}
 
/* Then: */
new Child().set( "name", "Smiling" ).setSeveral( map );


I'm not sure how Javac and JVM would implement this. Maybe create a "shadow" void setSelfGeneric(Object,Object) method, and then create a bridge method to it in any subclass, which just calls it, and returns this.

If user were allowed to return a different Object than this, ie another Object of the same class as implementation, then it would need to check the type in runtime.

Interfaces could declare Self-Return method types as well.

Not sure whether Self-Return methods should be allowed not to be final (except when they're abstract). If subclass might change the behavior, then final Self-Return method can call a non-final protected method to do the job.

peterkehl

Posts: 4
Re: Generic "this" ("self") method return type
Posted: Jan 28, 2005 12:51 PM   in response to: peterkehl
  Click to reply to this thread Reply

It would also clarify behavior of Object.getClass(), which must have special support of compiler, as its Javadoc says:

"Returns:

The java.lang.Class object that represents the runtime class of the object. The result is of type Class<? extends X> where X is the erasure of the static type of the expression on which getClass is called."

tackline

Posts: 238
Re: Generic "this" ("self") method return type
Posted: Jan 29, 2005 4:28 PM   in response to: peterkehl
  Click to reply to this thread Reply

You can do some similar with only 1.5 facilities. Give the base class a generic parameter that represents a type "like this". Either cast this, or return the return value of an abstract "get this"/self method.

public abstract class Base<THIS extends Base> {
private int x;
private int y;
@SuppressWarnings("unchecked")
public THIS location(int x, int y) {
this.x = x;
this.y = y;
return (THIS)this;
}
}
public class Concrete extends Base<Concrete> {
}

Or

public abstract class Base<THIS extends Base> {
private int x;
private int y;
protected Base() {
assert this == getThis();
}
public abstract THIS getThis();
public THIS location(int x, int y) {
this.x = x;
this.y = y;
return getThis();
}
}
public class Concrete extends Base<Concrete> {
public Concrete getThis();
return this;
}
}

I must admit, I've only tried it once and didn't like it much in that particular situation.

Personally, I'd prefer a notation that allows a chain of method invocations on a single expression.

peterkehl

Posts: 4
Thx: Generic "this" ("self") method return type
Posted: Jan 31, 2005 5:30 AM   in response to: tackline
  Click to reply to this thread Reply

Thank you, Tackline.

It perfectly does the job.

kfgodel

Posts: 19
Re: Thx: Generic "this" ("self") method return type
Posted: May 4, 2006 7:20 AM   in response to: peterkehl
  Click to reply to this thread Reply

Even though passing the concrete class in a type variable can fix your problem, I think it is cumbersome.
Imagine passing by type parameter an already parametrized class. Your typing can grow exponentially, and your clarity become null very quickly.
I still think that a way of saying something like "this" for the actual concrete type is necessary and serves the clarity of expressions in the language




 XML java.net RSS