Is there a way to say “method returns this” in Java?

前端 未结 3 703
终归单人心
终归单人心 2020-12-18 07:54

Is there a way to say \"this method returns this\" using Generics?

Of course, I want to override this method in subclasses, so the declaration should wo

相关标签:
3条回答
  • 2020-12-18 08:03

    No, there's no way of expressing that. Just declare the method to return the type of the class. Java has covariant return types, so you can override a method to return a more specific type anyway.

    If you wanted to have some marker for this, you could always introduce your own annotation - but don't expect any other tools to take any particular notice of it.

    EDIT: the answer from oxbow_lakes does indeed give something which will work in most cases, but I believe there are ways of fooling it such that you're actually dealing with a different type. (From memories of experimentation, anyway.) Note that this is similar to how Java enums work.

    0 讨论(0)
  • 2020-12-18 08:09

    You can do something very clever (and akin to what they have done in Scala with the 2.8 collection framework). Declare some interface method that should return "itself" (Note: This is a type parameter, not a keyword!)

    public interface Addable<T, This extends Addable<T, This>> {
       public This add(T t);
    }
    

    Now declare a level of indirection - a "template" class

    public interface ListTemplate<A, This extends ListTemplate<A, This>> 
        extends Addable<A, This>{
    }
    
    public interface List<A> extends ListTemplate<A, List<A>> {
    }
    

    Then an implementation of List has to return a List from the add method (I'll let you fill in the impl details)

    public class ListImpl<A> implements List<A> {
    
        public List<A> add(A a) {
            return ...
        }
    }
    

    Similarly you could have declard a SetTemplate and a Set to extend the Addable interface - the add method of which would have returned a Set. Cool, huh?

    0 讨论(0)
  • 2020-12-18 08:19

    using covariant types should be simple as:

    abstract class Foo<T> {
    
        Foo<T> get() {
            return this.getClass().cast(this);
        }
    }
    
    class Bar extends Foo {
    
        @Override
        Bar get() {
            return (Bar) super.get();
        }
    }
    
    0 讨论(0)
提交回复
热议问题