[Logo]
Forums Register Login
What is the real meaning of the extends keyword in generic methods?
Good people of this forum, please lend me your usual expertise.
I have something like this:
<P extends D>
And I am thinking that the range of classes covered by the expression is:
  |----------------------------------------------|
  D                                                        Subclass of D
So that I could do things like:

Wishful thinking!  So now, I have the following newbie program and the <P extends D> breaks it.   I am pleading for explanation as to why the generic method is rejecting the <P extends D>.



 

Biniman Idugboe wrote:. . .

I hope you don't format code like that in real life. The lines are too long, and the long comments make it difficult to read. This is what I think that code should look like:-I have removed the comments which confuse the code, and broken the long lines, so you can see how to do it. But even now thee lines are a bit too long. That is why the text is too wide for the screen. Also don't use tabs for indenting: use spaces, for reasons explained here. Don't use _underscores_ in identifiers. Don't call a method getInstance because that name is already reserved for factory methods. Use // not /* &hellip */ for commenting code out.

Also what is the relevance of that code to the question in the thread title? You are nowhere using List<E extends Dog> or anything like that. The nearest you get to it is in your line 29. Does your code actually compile? All P extends D means is you are saying that the 3rd parameter must have an actual type parameter which is a subtype of the 1st type parameter. Remember that for the purposes of generics, every type is a subtype of itself. So if you pass Dog as the D and the P has to be a Dog or one of its subtypes. You have made things less clear by using the same letters as the classes start with. C doesn't have to be a Cat. P could be an Alsatian or a Boxer or a Chihuahua or a Dachshund or even a Dog plain and simple.
Of course if the code doesn't compile, you have a different problem. You do not have a 3rd independent generic type; you would have to declare the method as ...<D, C>... and give the 3rd parameter the type List<E extends D>
Thanks Mr. Campbell.  I have edited the code as shown below.  The compiler is still unhappy.



error: > expected
        public <T, V> V fetchInstance(List<T> tList, List<V> vList, List<W extends T> wList)
                                                                                                        ^



Here is a similar program that compiles and runs without error. 
***********************************************************************



What is exactly the difference between the extends keyword  in the copy() method and the extends keyword in the  getInstance() method?
 

Biniman Idugboe wrote:What is exactly the difference between the extends keyword  in the copy() method and the extends keyword in the  getInstance() method?



As far as I can see, there isn't any difference. But I had to spend several minutes scrolling back and forth through the thread to find those methods, so I can't be sure I found the right things. It would also help if they were close together so that they could be compared without having to scroll back and forth, although maybe they were, it was not easy to see them given all the other code in the thread.
Okay, so let's copy them to the same place so they can be compared.





That's the methods you were asking about, right? So yes, as far as I can see the "extends" keyword is used in the same way in both places.
 

Biniman Idugboe wrote:
error: > expected
        public <T, V> V fetchInstance(List<T> tList, List<V> vList, List<W extends T> wList)
                                                                                                        ^



First, do you have the generic W declared anywhere? The fetchInstance() generic method only declares T and V. And second, do you have a class T declared anywhere? If memory serves, bounded generics are bounded by class/interface types -- not sure if you can bound it with a generic (need to confirm this though... ).

Henry
Thanks for your responses.  As I said previously, the code compiles and runs when I use:


Instead of:

And I am asking to know what the W extends T is saying to the method.


<T>  is replaced with <Dog>
<V> is replaced with <Cat>
<W> is replaced with <Poodle> and Poodle is a legal subclass of Dog. So, what is the compiler complaining about?
I only think you are allowed extends and maybe super when you have the name of a type before it.
List<E extends Foo> OK
public final <T extends Foo> T someMethod(T t) No

[Additional]I may be mistaken. You will have to check whether this is permissible or not:-
public final <T> T someMethod(T extends Foo t) It doesn't look right, but I don't have time to try it now.


In view of Henry's post following, I think I was mistaken here.
 

Biniman Idugboe wrote:
And I am asking to know what the W extends T is saying to the method.

<T>  is replaced with <Dog>
<V> is replaced with <Cat>
<W> is replaced with <Poodle> and Poodle is a legal subclass of Dog. So, what is the compiler complaining about?



As already mentioned, the compiler is complaining about the bound. Bounded generics are bounded by the class/interface types -- and not other generics. There is no substitution here. Hence, the compiler is looking for a generic W that extends the class/interface type T. And do you have a class/interface named T?


Interesting. I just tried it, and you can bound a generic with a generic. Learned something new...

Henry
In which case I think I may have been mistaken earlier. My apologies.
 

Biniman Idugboe wrote:So, what is the compiler complaining about?


Both declarations are legal. I don't see the compiler complaining. Can you post the complete and exact code snippet that you can't get to compile?
Here's the complete code.
(1 like)

The issue is the makeArrayList() method. The compiler can't confirm the W is bounded by T for the fetchInstance() method, because it may not be bounded.

If you modify the makeArrayList() generic method to also require the bound, then the code should compile.

Henry

PS... sorry, about the red herring earlier.
What a relief!  I cannot thank you enough. So many nuances in Java.
Wink, wink, nudge, nudge, say no more ... https://richsoil.com/cards


This thread has been viewed 250 times.

All times above are in ranch (not your local) time.
The current ranch time is
Jun 22, 2018 14:58:56.