• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Help: about the <? extends T>

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
class Point{
}
class SubPoint extends Point {
}

public class Test {

public static void main(String[] args) {
List<? extends Point> listExtends = new ArrayList<SubPoint>();
listExtends.add(new Point()); //not compile #1
listExtends.add(new SubPoint());//not compile #2

List<? super SubPoint> listSuper = new ArrayList<Point>();
listSuper.add(new Point());//not compile #3
listSuper.add(new SubPoint());// #4
}
}
PS:JDK 1.6
why the #1,2,3 does not compile and the #4 can be compiled.
thanks .
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

List<? extends Point> is a list that holds some unknown type that extends points. The key here is that it is unknown, it doesn't know if it is holding Point, holding SubPoint, or holding the, yet to be developed in the future, SubSubPoint. So, since it can't figure it out, it won't allow you to add anything. The only exception is null, since in that case, null can by any type.

List<? super SubPoint> is a list that holds some unknown type that is a super of points. This means that it can be SubPoint, Point, or even Object. You can't add a Point, because it may be a SubPoint. You can add SubPoint, because a SubPoint IS-A Point, and IS-A Object.

Henry
 
Ranch Hand
Posts: 808
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And with List<? extends Something> list you can not add anything to the collection, nevertheless with List<? super Something> lisy you can add. This is because there is no equivalent exception for the collections as for the arrays - ArrayStoreException
 
Ranch Hand
Posts: 327
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was going to post this earlier, but ran out of time. I use Animals, Dogs and Cats when thinking about this. They're obvious, easy to remember and everyone knows that if you get Cats and Dogs into the same room without strict controls, the fur will fly!

<? extends T>
As Henry has said, this means any container that contains things that are T or are subtypes of T. Consider:So why is the first one bad and the second not? Well, they're both bad and could cause untold mayhem at runtime. In the second case the compiler cannot "see" that otherDogs array (Animal[]) actually points at a Dog array (Dog[]). Cat IS-A Animal, so the compiler thinks it's Ok. The JVM, however, then winds up with a Cat inside it's nice, orderly Dog array and all heck breaks lose. You can still pass a List<Dog> to a List<? extends Animal>, but not add to it (apart from null, of course); the compiler "knows" that any List of things that extend Animal could have been added (Cat, Dog, Mongoose...) so it stop you adding anything to it in order to save the JVM grief.

<? super T>
Well, consider this::So why does this work? Haven't I just added a Cat to my Dog List? Won't they fight? Won't the JVM get taken away for Animal cruelty? No. Because I did not add a Cat to a Dog List. Not me. No sir! I added a Cat to an Animal List that just happened to contain a Dog. Cat IS-A Animal, so of course it can be added to an Animal List. With <? super T> I can pass in a List of Ts or any supertype of T aaaaaalll the way up to Object if I want; but I cannot add anything lower than a T. Why? Well, T can be added to a T List, it can be added to a Super-T List, it can be added to an Object List; but it cannot be added to a Sub-T List (Cats and Dogs again).

You mostly (but not exclusively) see <? extends T> or <? super T> on the arguments to method calls.

Summary:
for <? extends T> you can pass in T or anything that extends T, but not add anything (other than null).
for <? super T> you can pass in T or any supertype of T, but you are only allowed to add T.

Just make sure you pick the correct one, or you could wind up with some very strange code/interfaces.

Hope that helped someone - it helped me.
 
Sheriff
Posts: 7134
1360
IntelliJ IDE jQuery Eclipse IDE Postgres Database Tomcat Server Chrome Google App Engine
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have a look at GenericsSuperAndExtends
 
Lucas Smith
Ranch Hand
Posts: 808
1
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Great article Devaka! Thanks.
 
Ke Haiyang
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thank you very much,
now, i understand the question well.
 
reply
    Bookmark Topic Watch Topic
  • New Topic