• Post Reply Bookmark Topic Watch Topic
  • New Topic

Can't Pass ArrayList of Class Implementing Interface to Method Expecting ArrayList of Interface?  RSS feed

 
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a class C that implements interface I. I can pass instances of C to methods that expect parameters of type I, but I can't pass ArrayLists of instances of C to methods that expect ArrayLists of type I.

Why not?
 
Marshal
Posts: 56608
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Although you can legitimately write new C instanceof I and expect true, the same does not apply to generic types.
If you go through the Java Tutorials, you find that if X is a subtype of Y, then a List<X> does not count as a subtype of List<Y>. If there is a section about bounded types in the Tutorials link, read that.
You may have to declare one variable as List<? extends I>, but remember that you can usually not add things to a List<?...>
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. That explains it. Apparently, I have fallen prey to the common mistake of thinking List<X> is a subtype of List<Y> if X is a subtype of Y. List<X> and List<Y> are actually subtypes of List<?>, with no relationship implied for List<X> and List<Y> themselves.

It's a bit deep into the tutorial, but a good page on it is here.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Applying what you pointed me towards, this appears to be the way to do what I was trying to do:
With the important bit being the difference at Line 17.
 
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, that's one way to solve it. Another way is to make the method m2 generic (give it a type parameter):
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the alternative method, Jesper (documented here in the tutorials).

Are there any ways you can suggest to choose between these options?
 
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Are there any ways you can suggest to choose between these options?

Well, as Campbell said, the wildcarded version (the one with the '?') doesn't allow updates; so if you need to update the List, there's only one alternative. It's also more common to see Jesper's style on static methods; but it's certainly not wrong to use it on instance ones.

On balance, I'd choose Jesper's style if it's applicable, simply because it has fewer restrictions; but there are no hard and fast rules about it.

HIH

Winston
 
Campbell Ritchie
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:Thanks. . . .
You're welcome
And I think I prefer Jesper's solution, too.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That really does look like the best option. It's a rather subtle extension of what's in the tutorials, which don't directly address generic methods and wildcards (at least, not on the page I linked to, above). Been doing some experiments with it, as I find generics are taking me some time to wrap my head around. They seem easy to understand when you are providing the class for an implementation that uses them (as in, "ArrayList<MyClass>"), but they get a lot more... awe inspiring when you have to code them (as in, "public static <T extends I> void m(ArrayList<T> a)").

The original example I gave was pared down to the least code that would define the issue. The practical problem I'm working on actually just uses the ArrayList<> as a kind of variable-length parameter list to a method. I don't use the list within the caller, so I suppose I can also just redefine the list in the first instance as being composed of items of type I, not C.


If one were stuck with a method that only took ArrayList<I> as its argument (that is, one were not in a position to rewrite the method), would there be any other way to handle this?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:...but they get a lot more... awe inspiring when you have to code them (as in, "public static <T extends I> void m(ArrayList<T> a)").

Just wait till you run into
<T extends Comparable<? super T>>

However, it is all explained in the tutorial (at least the one by Gliad Bracha).

Winston
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:Just wait till you run into
<T extends Comparable<? super T>>

I get the distinct feeling that, if I ever encounter any such horror, it will be running into me.

*sigh*

It all seemed so easy, back when it looked more like this:

Anyway, you guys are an amazing bunch. I've never found a forum as informative and supportive as this one. Thanks.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:It all seemed so easy, back when it looked more like this:

Oh, but that is just as easy in Java as it is in BASIC, ofcourse....
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, yes. In the end, all programs based on finite-state automata can be transliterated into something like this:



And what could be simpler than that?

 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!