1
interface Receiver {
    public <T extends HasId> void doSomethingWithList(List<T> list);
}

also,

class SubClass implements HasId {}

but

List<SubClass> list = getList();
receiver.doSomethingWithList(list);

fails to compile, complaining doSomethingWithList is not applicable for the arguments List<SubClass>

Where's my mistake?

Riley Lark
  • 20,660
  • 15
  • 80
  • 128
  • 1
    Can you post the actual error? – pickypg Apr 18 '11 at 03:15
  • This morning, there isn't one. Argh. Sorry everyone - I guess my computer was tired. Yeah, I'll blame it on the computer. Anyway, I just went to bed and came back and it compiled fine. – Riley Lark Apr 18 '11 at 12:43

3 Answers3

3

It looks fine to me. Can it be that you used the wrong List class (i.e. not java.util.class but java.awt.List) in one of the declarations. Perhaps in the interface. Can you double-check import statements? I've made this mistake myself in the past, and it is valid lead on this case :-)

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
  • The problem with your example is that the `Integer` you create is _not_ of type `T`... you're just pretending it is, which is a really bad idea since your method can take `List`, `List` etc. The compiler is absolutely correct in preventing you from doing that in my version of the method. I did think of one valid scenario, something like sorting the `List`, where it would make a difference to keep the `T` though. – ColinD Apr 18 '11 at 04:46
  • No, according to the method signature, the list contains _some specific subtype_ of `Number`. If it was a `List` that could legally contain numbers of any type, it'd have to be `List`. Your example happily allows adding an `Integer` to a `List` (that is, a `List` that is only allowed to contain instances of `Double`), which would invariably result in a `ClassCastException` at some point. – ColinD Apr 18 '11 at 05:02
  • Since changing the method signature does slightly reduce the range of possible things an implementation of that interface could do with the `List`, I'm deleting my answer since it's kind of pointless. – ColinD Apr 18 '11 at 05:14
  • @CollinD The discussion was rather interesting despite of contention. You proved to be right regarding instantiation of T. Quite a lesson for me, thanks!. It is almost midnight on my end of the wire, so I´ve got to go get some sleep. I will be editing the question to remove the unnecessary details that lead to our discussion since I feel they do not add anything to finding the root cause of the original problem. – Edwin Dalorzo Apr 18 '11 at 05:17
  • I marked this the answer for the helpful lead. In the end, I'm not sure what was wrong. Despite the fact that I cleaned and recompiled like 3 times, only a restart of my machine seems to have helped. Argh! – Riley Lark Apr 18 '11 at 12:44
3

code compiles fine without any problem.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • Which means that the theory that the wrong List was used in the import declarations gains more relevance :) – Edwin Dalorzo Apr 18 '11 at 05:24
  • Is this an actual answer? Should probably be a comment, right...? – bitxwise Apr 18 '11 at 05:57
  • question: why 1+1 != 2 ? answer: 1+1==2. – irreputable Apr 18 '11 at 16:02
  • Just saying, if the OP is actually having issues with his code compilation, a simple "works for me" doesn't really answer his question...Also, if HasId is a class and not an interface, then it should NOT compile. But it seems that the OP got it working after a reboot so oh well. – bitxwise Apr 18 '11 at 18:37
0

Like irreputable, my quick implementation of your code compiles and runs just fine. Perhaps this can give you some leads; perhaps the issue has more to do with your implementation in regards to Java's support of generic polymorphism.

It seems that you're using an interface rather than class inheritance, but your question title says List<T extends SuperClass>...

Community
  • 1
  • 1
bitxwise
  • 3,534
  • 2
  • 17
  • 22
  • That is the proper syntax for generics using interfaces. It's a bit counterintuitive, but it is what it is at this point in Java. – pickypg Apr 18 '11 at 13:55
  • Right, I know it's the proper syntax for using interfaces but the OP said "SuperClass" in the question. So if HasId is a class and SubClass extends it, then it shouldn't compile. Notice the OP did not specify whether HasId is an interface or a class. – bitxwise Apr 18 '11 at 18:32
  • The method signature practically is `public void doSomethingWithList(List extends HasId> list)`, which should work whether or not `HasId` is a `class` or `interface`. – pickypg Apr 18 '11 at 18:49
  • If `HasId` is a class, then that's not true for a method accepting a `List extends HasId>`. Look at the link I posted in my answer. – bitxwise Apr 18 '11 at 18:51
  • The explanation in the link you posted is a good one. However, it does not describe the problem you are describing. In our example, `HasId` is `Animal`. `Animal` can be an interface or a class. In `doSomethingWithList`, he just wants a `List` of `"Animal"`s (`HasId`s). In other words, he wants to be able to pass in `List` or `List` (or even `List`) without limiting it to either one, yet still require that the generic type be some type of `Animal` (`HasId`). I will say, it may be simpler to just specify it as `void doSomethingWithList(List extends HasId> list);` – pickypg Apr 18 '11 at 19:16
  • Just re-read it. Class-wise it should work too (the difference between a method accepting `List` and `List extends Animal>`); this is what I get for posting at 4AM @_@ – bitxwise Apr 18 '11 at 20:50