I have a generic class A<T>
and a subclass B extends A<String>
.
The class A have a method which returns this (so an A<T>
).
The problem is, if I call the method on a B object, it will return a A<String>
and I have to cast to B, but B is the same as A<String>
, isn't it ? So I shouldn't have to cast ...
Asked
Active
Viewed 76 times
0

dblouis
- 568
- 1
- 5
- 18
-
is a `porsche` the same as a every `car`? – SomeJavaGuy Aug 16 '16 at 10:57
-
1Please show your code... it sounds like you can use a covariant return type. – Andy Turner Aug 16 '16 at 10:57
-
1You need the [return SELF](https://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current-type-with-a-type-variable) pattern. It's a bit ugly, but works. This is an example of the [curiously recurring template pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). – Boris the Spider Aug 16 '16 at 10:57
3 Answers
1
If your method returns A<String>
it can be an object of type B
but it does not have to be!
If you have a superclass of type car
and BMW extends car
.
Consider a factory that creates a car. The method returns car - this can be a BMW but it does not have to be a BMW.

Stefan
- 2,603
- 2
- 33
- 62
-
1Because I could create another class which also extends A
, I have only one so I did not see that ... – dblouis Aug 16 '16 at 11:01 -
@L.DUPRÉBERTONI this isn't really an answer to the question, which has a good solution. If I know that I have a `B`, and a method in the superclass returns `this`, then I would expect it to return a `B`; but the method will actually return an `A
`. The way around this is the curiously recurring template pattern. – Boris the Spider Aug 16 '16 at 11:14 -
1@BoristheSpider the question was about the understanding why he has to cast - I think I clearly answered this question. If you find yourself having another question feel free to post it as an answer to his question – Stefan Aug 16 '16 at 11:15
-
The point is that "_[t]he class `A` have a method which returns `this`_". If have created a `new B()` then we know that `this` can never by _anything else_. This answer answers a different question, not the question asked. I believe that the OP doesn't really understand the problem, and has selected the wrong answer... – Boris the Spider Aug 16 '16 at 11:32
0
I overrided the method and cast the returned value so that I don't have to do it everywhere. Thanks @AndyTurner

dblouis
- 568
- 1
- 5
- 18
0
You don't even have to cast. You can override the method and change the return type to B, as it's still an A<String>
which is an A<T>
, so it's valid for B.
class A<T> {
public A<T> return_this() {
return this;
}
}
class B extends A<String> {
@Override
public B return_this() {
return this;
}
}
So you can do this:
B b = new B();
A<String> a = b.return_this(); //Because B extends A<String>
B b = b.return_this();

germanfr
- 547
- 5
- 19
-
This does work, but becomes quickly untenable if there are large number of methods. – Boris the Spider Aug 16 '16 at 11:35
-
-
As I said it depends. This solution is simple and works when you have one or two methods and one or two classes in the hierarchy. It becomes unmaintainable if there are a large number of methods returning self types; such as in a fluent accessor or builder pattern. In that case the curiously recurring template pattern is required. Casting is never an option however. – Boris the Spider Aug 16 '16 at 11:43