1

I just saw a class declaration in our codebase that looks like this:

public abstract class SomeClass<T extends SomeClass<T>> implements Cloneable {
    ...
}

After learning from a couple of tutorials on Java generics, now I understand stuff like SomeClass<T extends Comparable<T>.

However, SomeClass<T extends SomeClass<T>> still doesn't make sense to me. Apparently, T must derive from SomeClass<T>... but SomeClass has not been declared yet! What is happening here?

Any help is appreciated!

Chen Ni
  • 979
  • 1
  • 12
  • 24

1 Answers1

2

Most probably, inside the abstract class there something like this:

public abstract class SomeClass<T extends SomeClass<T>> implements Cloneable {
    public abstract T someMethod(); //<-- variable return type should be the implementing class itself

    public abstract int someOtherMethod(T someInstance); //<-- variable parameter type should be the implementing class itself
}

With such declaration, when you extend the class SomeClass with something concrete, let's say SomeConcreteClass, then you'll have:

public class SomeConcreteClass extends SomeClass<SomeConcreteClass> {
    @Override
    public SomeConcreteClass someMethod() {
      //implementation that returns SomeConcreteClass
    }

    @Override
    public int someOtherMethod(SomeConcreteClass instance) {
      //implementation that takes in parameter this type of class
    }
}

When you declare an abstract class like that, you basically ask to self-reference the child class in the parameter type.

Of course you may also use another child (it would still be inside bounds as long as it extends SomeClass), but it's a rare use case (I'll never seen it personally)

Matteo NNZ
  • 11,930
  • 12
  • 52
  • 89