This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
You have some code that you want to introduce some change in.
Yes. It is my own sketch.
Jonas Isberg wrote:
Your suggested change wont work, but you believe it should have worked.
I didn't suggest any change, rather I ask readers for this change.
Jonas Isberg wrote:You donnot say exactly what problem you have with your suggested change.
I have said absolutely exactly - with code fragments (it isn't possible to be more elaborate ) - about the aim. Please look at the first post. At the end you will find two single-string snippets - with (working case) and without (not compilable call - inference doesn't work the way I expect) type parameter.
I think this question is quite clearly asked, actually.
The problem seems to be that you're mixing interfaces and implementations in your code. When you declare the list variable as List<String> instead of ArrayList<String>, the line which didn't work will be compiled without problems. You'll start having issues with line 65 instead, but again, declare r3 as Res<List<String>>, not ArrayList. You should declare variables using interfaces and not implementations, and this is just one of many good reasons to do so.
Martin Vajsar wrote:You should declare variables using interfaces and not implementations, and this is just one of many good reasons to do so.
Yes, of course. It was just use case example. In other more simple words, we have:
I see, 'B extends A' doesn't mean 'Res<B> extends Res<A>' (and it is most unexpected feature of Java generics, if I understand correctly). But I have guessed explicit parameter in res2 declaration is sufficient to infer type parameter in 'Res.ok(new B())' method call.
Andrew Gaydenko wrote:I see, 'B extends A' doesn't mean 'Res<B> extends Res<A>' (and it is most unexpected feature of Java generics, if I understand correctly).
Yes, this is actually the problem in our case.
But I have guessed explicit parameter in res2 declaration is sufficient to infer type parameter in 'Res.ok(new B())' method call.
I'm not sure how, if or when the expected return type is considered in the type inferring mechanism, however, in this case, the type can (and is) fully inferred from the method parameters alone. The resulting type is then incompatible with the variable, as a consequence of the previous point.
By specifying the type in the method call, you're passing the List<String> where ArrayList<String> is expected, and these types are compatible. So no compiler warning here.
I'm still on Java 6, but I believe Java 7 hasn't changed these rules, except of the diamond operator, which doesn't apply here.