• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generics question  RSS feed

 
Adam Chalkley
Ranch Hand
Posts: 257
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi I'm wondering why I get an error the error is when I'm calling the player method in main,I thought I had an idea of how generics worked but I must be horribly wrong so I'm wondering why can't you pass in listTwo as an arguement because Football Player is a subclass of player

but how come I don't get an error in the team class if I pass FootballPlayer as the type parameters Team<FootballPlayer>??

Player.java please note I have also two sub classes of player FootballPlayer and BasketballPalyer




Team.java



main.java



thanks
 
Henry Wong
author
Sheriff
Posts: 23188
124
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Chalkley wrote:
but how come I don't get an error in the team class if I pass FootballPlayer as the type parameters Team<FootballPlayer>??


A FootballPlayer instance, IS-A Player instance, IS-A Object instance ... so ... you can place in in a Team<FootballPlayer>, Team<Player>, or Team<Object> instance.

... and BTW... the Player in the Team class declaration isn't a Player instance, it is a generic with Player as the generic variable. This, of course, can get really confusing.

Henry
 
Adam Chalkley
Ranch Hand
Posts: 257
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks for the reply Henry

I'm still quite confused I must say
 
Knute Snortum
Sheriff
Posts: 3715
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maybe this link will help?
 
Stephan van Hulst
Saloon Keeper
Posts: 7376
130
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Henry has mentioned before, the name of your generic type parameter is the same as the name of a class. That is extremely confusing and won't help you to understand your own code. Other problems include:

  • You're using raw types. Enable your compiler warnings to eliminate them.
  • Your class and your fields are not final. Make them final unless you have a good reason not to.
  • The type of your members field is too specific. Do you really need an ArrayList, or will a regular List or even a Collection do? ¹
  • You're not checking your parameters. Always check if their values are valid and throw an exception if they're not.
  • You're using an old style for-loop where you can use an enhanced for loop. In many cases however, you can also use the Iterable.forEach() method.
  • Your class is Comparable, but you didn't override equals() and hashCode(). ²

  • The following remarks contain some advanced code snippets. You may not understand all of them, but they may act as good examples when you explore the more advanced concepts of generics.

    ¹ In this case, you may want to make a separate class to hold a hierarchy of members. That way, you can keep your team ordered, and also implement the compareTo() method easily. Here's what it could look like:


    ² The problem with making your class Comparable is that there is no obvious way to make it consistent-with-equals, and still use it as a key in, for instance, a TreeMap. This is because your class is mutable. In general, only immutable classes should implement Comparable. Let's make your Team class immutable, and give it a compareTo() method that's consistent-with-equals:

    You can use this class like this:

    This code assumes that the FootballPlayer class implements Comparable<FootballPlayer>, and compares players by their shirt number and name.
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks Stephen

    I'm reading the oracle docs tutorial (https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html) and I still can't figure out the difference between these two instances



    is legal




    and this is not when you pass lets just say Box<Double> into the method the thing I don't get is why is the first snippet of code valid aren't you basically doing the same thing? in the first snippet you can do box.add(new Double(10.1)); because has a is a relationship with number and in the second snippet isn't this the same thing because Double is a number

    I don't get this part of the tutorial

    What type of argument does it accept? By looking at its signature, you can see that it accepts a single argument whose type is Box<Number>. But what does that mean? Are you allowed to pass in Box<Integer> or Box<Double>, as you might expect? The answer is "no", because Box<Integer> and Box<Double> are not subtypes of Box<Number>. 


    but if that's the case how come the first snippet of code is valid?

    thanks
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:I still can't figure out the difference between these two instances

    is legal


    An Integer instance IS-A Number, hence, the first add() method call is allowed. A Double instance IS-A Number, hence, the second add() method call is allowed.

    Henry
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:

    and this is not when you pass lets just say Box<Double> into the method the thing I don't get is why is the first snippet of code valid aren't you basically doing the same thing? in the first snippet you can do box.add(new Double(10.1)); because has a is a relationship with number and in the second snippet isn't this the same thing because Double is a number


    In this code snippet, you can't pass a Box<Double> instance because a Box<Double> instance is *not* IS-A Box<Number> instance.

    Just because a Double instance IS-A Number instance, does not mean that when used as generics, their Box class equivalents are also. You need to understand both features separately, and apply it accordingly.

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    hey Henry thanks for the reply I understand that but I don't understand the difference between the first snippet and second snippet of code
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks Henry I find that concept very complicated =(
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:hey Henry thanks for the reply I understand that but I don't understand the difference between the first snippet and second snippet of code


    Let's take the code snippet out of this and use a simple analogy...

    Let's say you have a box that only holds puppies. You can put any type of puppies into this box. This is also a good idea because puppies are cute, and they should stay together.

    Let's say you have a box that holds any type of animal. It could be puppies. It could be kittens. It could also be a alligator that will eat those puppies and kittens. Of course, this box is horrible -- as you don't know what type of animals are in this box.

    Now... based on your reasoning, since a puppy IS-A animal, then a box of puppies IS-A box of animals, and hence, you can put any type of animal into a box of puppies. Do you really think that it is a good idea to put an Alligator into a box that is only supposed to hold puppies?


    Or in summary, to understand the first snippet, you need to understand the hierarchy of Numbers and Integers. And to understand the second snippet, you need to understand the Box class, and how they the generic type are applied. These are *not* the same thing.

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Henry that makes a little more sense thanks for the help
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7376
    130
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you have a Box<Number>, it will have a method add(Number). Because Integer and Double both are sub-types of Number, you can assign them to variables and parameters of type Number. That means you can pass Integer and Double to add(Number).

    However, a Box<Double> is NOT a sub-type of Box<Number>. So if you have a method that accepts a Box<Number>, you can NOT pass it a Box<Double>.

    So the real question is: Why is Double a sub-type of Number, but Box<Double> not a sub-type of Box<Number>? Imagine if it was:

    Because we could assign a Box<Double> to a Box<Number>, we were able to add an Integer to a Box<Double>. This would result in a ClassCastException at runtime, exactly the kind of thing that generics are meant to prevent.

    So what is the direct super-type of both Box<Double> and Box<Integer>? That would be Box<? extends Number>. If you have a method parameter or a variable of type Box<? extends Number>, you can assign it any kind of Box, as long as its generic type argument is a sub-type of Number.

    In general, you use <? extends Something> when you have a generic type that you only want to get elements OUT of, and you use <? super Something> when you have a generic type that you want to put elements IN. Take a look at my Hierarchy class above. It has the following constructor:

    The elements parameter uses the extends keyword, and the comparator parameter uses the super keyword. This is because we only take Ts out of the elements collection, and never put Ts into it, and we only put Ts into the comparator (when we call comparator.compare()), and never get Ts out of it. We say that elements is covariant, and comparator is contravariant.
     
    Campbell Ritchie
    Sheriff
    Posts: 54495
    150
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Stephan van Hulst wrote:. . . if you have a method that accepts a Box<Number>, you can NOT pass it a Box<Double>. . . .
    Stephan has shown how allowing a Box<Double> to be a subtype of Box<Number> is like trying to sell the compiler a pig in a poke. There used to be a section in the Java™ Tutorials showing the relation between Cages, with Cage<Animal>, Cage<Butterfly> and Case<Lion> examples, similar to Henry's box of puppies. I think you would have to look for old versions of the Java™ Tutorials to find it. Sometimes the same explanation is clearer if you read it in several places.

    By the way: If you ever find the Java5 tutorials version, read what it says about enumerated types being better in Java® that other languages
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks Stephan for the detailed post that makes a little more sense just a few questions


    why is Box<? extends Number> the super type of of box<Number> and box<Double>?


     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    and why would



    give a compilation error?

    thanks
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:and why would

    give a compilation error?


    Well, first, you do know that a bounded wildcard, as in your example, does *not* mean a Box that can hold Number and any of it's subclass right? It is still a  box of Double; it is just that the compiler doesn't know what the generic is.

    And second, even if the compiler does know what the generic type is, you are not allowed to place an Integer into a Box<Double>. So, in this case, the compiler correctly forbid the compilation, even though it didn't have enough information to confirm the type.

    Henry
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    And also...

    Adam Chalkley wrote:
    why is Box<? extends Number> the super type of of box<Number> and box<Double>?


    Box<? extends Number> is *not* the supertype of Box<Number> or Box<Double>.  It is simply assignable... Generics (along with wildcards) are a bit more complex than what is IS-A type for assignment purposes.

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    question if ArrayList<? extends Object> is a direct super type of ArrayList<String> and ArrayList<Object>

    how come this code does not work?

     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    also can someone explain this method definition to me


    binarySearch(List<? extends Comparable<? super T>> list, T key)

    I understand the first part that this method takes a list that implement the interface Comparable,but what does the <? super T> after Comparable mean?

    thanks
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:


    Please don't mix wildcards with the diamond operator. With the diamond operator, the compiler has to infer the generic type. And with wildcards, I am not sure if what you think would be inferred, would be what the compiler inferred.... not that it really matters, as the only reference to the instance is via a wildcard.

    Adam Chalkley wrote:


    With the wildcard, the compiler can't determine that the generic type IS-A String. It just so happens that it is, so it should be allowed ... but the compiler can't confirm it, so it isn't allowed.

    Adam Chalkley wrote:


    With the wildcard, the compiler can't determine that the generic type IS-A Object. It happens to be String, so it should not be allowed, but regardless, the compiler can't confirm it, so it isn't allowed.

    Henry
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:
    I understand the first part that this method takes a list that implement the interface Comparable,but what does the <? super T> after Comparable mean?


    You quoted the example out of context. You need to also include the part of the example that declares the T generic.

    Henry
     
    Campbell Ritchie
    Sheriff
    Posts: 54495
    150
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote: . . . binarySearch(List<? extends Comparable<? super T>> list, T key) . . .
    I presume you mean this method. Let's start by having another look at Comparable. Note it is called
    Interface Comparable<T>
    at the top of that page. So let's try working out a T or two:-You can have a Fahrenheit class, a Réaumur class etc in that package, but no non‑temperature classes. So the Temperature class cannot be subclassed outside the package, and the other classes being final can't be subclassed at all. Now let's have a List<Temperature> containing objects of different scales. Now, temperatures do implement a total ordering; you can always say that warmer == more, and you can also say that 20℃ is the same as 68℉. You don't want each subclass of Temperature to implement compareTo; indeed you can't because I marked it final. But each subclass can use the superclass' method because each can calculate a °K value.
    So far, so good. We have a (correctly‑implemented) compareTo method (which might not return 0 because the imprecision of doubles means it might not make 20.4℃ equal to 68.72℉). We have that method inherited by all kinds of Temperature. If you try to sort a List<Temperature> with Collections#sort(), you can say it is a List<Temperature>.
    Now, you don't want any old type being sorted like that; what if it doesn't implement Comparable. So we try sorting a List<Comparable>. But what happens when you put a String into that List. Strings are Comparable too, so that won't work. But what you can do is make the generics generic. So rather than saying it is a T or a Comparable, you have to say it is a T which is Comparable to itself. Remember you always say extends in generics, not implements. You now have a generic type
    T extends Comparable<T>
    That means you have any type which implements the Comparable interface to compare to itself. In the next post I shall show you what goes wrong.
    Watch this space.
     
    Campbell Ritchie
    Sheriff
    Posts: 54495
    150
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    So, you are now trying to sort a List<Fahrenheit>. Of course you can do that, because Fahrenheit also implements Comparable (inherited from the Temperature class). So you try passing a List<Fahrenheit> to a sort method and it reads that as Fahrenheit implements the Comparable interface to compare to Fahrenheit. It will look for a compareTo(Fahrenheit) method and not find it. When you stop tearing all your hair out, you remember that it is the superclass that implements Comparable; it is Comparable<Temperature>. And there are bound to be other classes where the same happens. I don't think Vehicles have a total ordering, but let's imagine that they do, sorting by mileage on the clock. So Vehicle implements the Comparable<Vehicle> interface, and Car inherits it. This is obviously going to be a common problem. So what you are saying is:-
    I want to compare types which implement Comparable to themselves, or their superclass implements Comparable to itself. And we cannot specify what generic type that supertype is, so it has to go as ?. You write super T, so the generics for the sort method now becomes
    <T extends Comparable< super T>>
    That means any type which can be compared to itself or where its superclass can be compared to itself. Remember that for the purposes of generics, ever type is its own supertype and every type is its own subtype. So you can now write a sort method which will sort a List<Fahrenheit>

    So far, so good. What if you have a List<Taxi> and you are trying to find a taxi with the same mileage as your own Car. Well people do do some strange things. So you look for binary search, imagining it takes <T extends Comparable< super T>> as its generic type, and it won't take your List<Taxi>. Why not? Surely a Taxi IS‑A Car, and surely the Taxi class extends Car. And what if you are looking for a StretchLimo? Isn't that a subtype of Car, too? You know at the time that you are looking for a Car or one of its subtypes. So on the right of the Collections#binarySearch() method you have a T, and T or its supertype has to implement Comparable, so that gives you Comparable<? super T> as before for half your generics. But what about on the left? The simplest way to do it is ? pronounced unknown and we get
    <? extends Comparable< super T>>
    That means
    Any type which implements Comparable and can be compared to whatever we have in the other parameter, or compared to the other parameter's supertype.

    I hope that helps
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hey Campbell thanks for the detailed post much appreciated,I have a better grasp on it now but lets say in the example you used and in the BinarySearch Method

    binarySearch(List<? extends Comparable<? super T>> list, T key) .

    you use T,could we replace the question mark for a T and would it work the same ,what would be the difference?

    thanks
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    also whats the difference between
    <T extends Comparable< super T>>

    and <T extends Comparable<? super T>>

    ?

    thanks
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:Hey Campbell thanks for the detailed post much appreciated,I have a better grasp on it now but lets say in the example you used and in the BinarySearch Method

    binarySearch(List<? extends Comparable<? super T>> list, T key) .

    First of all, you have to give the full signature -- without the T declaration, you are posting code out of context. And as mentioned by Campbell, it is...
    Adam Chalkley wrote:
    you use T,could we replace the question mark for a T and would it work the same ,what would be the difference?

    The question mark in the example is a wildcard. The T in the example is part of a generic method. And while both of these are related to generics, they are different features... Here are the tutorial for more information on the subjects...

    Wildcards:  https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
    Generic Methods:   https://docs.oracle.com/javase/tutorial/extra/generics/methods.html

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    List<? extends Shape> is an example of a bounded wildcard. The ? stands for an unknown type, just like the wildcards we saw earlier. However, in this case, we know that this unknown type is in fact a subtype of Shape. (Note: It could be Shape itself, or some subclass; it need not literally extend Shape.) We say that Shape is the upper bound of the wildcard.

    There is, as usual, a price to be paid for the flexibility of using wildcards. That price is that it is now illegal to write into shapes in the body of the method. For instance, this is not allowed:



    You should be able to figure out why the code above is disallowed. The type of the second parameter to shapes.add() is ? extends Shape-- an unknown subtype of Shape. Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there.



    this is from the java docs ^^

    I don't understand what they mean by this line in particular and why this would be illegal

    you should be able to figure out why the code above is disallowed. The type of the second parameter to shapes.add() is ? extends Shape-- an unknown subtype of Shape. Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype,

     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:
    I don't understand what they mean by this line in particular and why this would be illegal
    you should be able to figure out why the code above is disallowed. The type of the second parameter to shapes.add() is ? extends Shape-- an unknown subtype of Shape. Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype,



    The explanation that you posted is pretty clear.  Can you explain to us what are you confused with? And what is it about the explanation that you don't understand?

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I don't understand what they mean by Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there.

    also why wouldn't this code work?



    Thanks Henry
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:I don't understand what they mean by Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there.


    This has been posted before, but clearly you should read it again. Here is the Oracle tutorial on wildcards...

    https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

    Adam Chalkley wrote:
    also why wouldn't this code work?


    Same reason -- just with different types.

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I read it but I don't understand that particular part
     
    Knute Snortum
    Sheriff
    Posts: 3715
    90
    Chrome Eclipse IDE Java Postgres Database VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    The key part is, What type is shapes?  It could be a Shape, but it might also be a subclass of Shape, say a Circle.  Now say you had this code:

    Would this code compile?  Obviously not.  Make sense?
     
    Knute Snortum
    Sheriff
    Posts: 3715
    90
    Chrome Eclipse IDE Java Postgres Database VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Adam Chalkley wrote:
    also why wouldn't this code work?



    Remember that the compiler is dumb.  It doesn't know that all Java classes extend Object.  (This is my guess, as I'm not an expert on compilers.)
     
    Henry Wong
    author
    Sheriff
    Posts: 23188
    124
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Knute Snortum wrote:
    Remember that the compiler is dumb.  It doesn't know that all Java classes extend Object.  (This is my guess, as I'm not an expert on compilers.)


    The compiler is not wrong here... It simply doesn't know the generic type of the Collection. Using the previous example (to explain), it could be a Collection<Rectangle> or Collection<Circle>, and with both of those cases, adding an Object instance is not allowed.

    Henry
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks guys I'm getting a better grasp on this now

    just a question how and why do I not get a compile error with this code



    for example I could potentially have an object called BasketballPlayer and it's instance called a and and its parent called Player and it's instance called b so if I call the method with swap(a,b) I am setting listTwo which is a List<Player> = to a basketballPlayer

    in other words

    List<BasketballPlayer> a = new List<>();
    List<Player> b = a;

    that would cause an error and break generic rules,so why are we allowed do it in that method?

    thanks
     
    Campbell Ritchie
    Sheriff
    Posts: 54495
    150
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    A Foo<? extends T> is a subtype of Foo<T>, so you can consider them as the same type. But try adding something to those Lists when you pretend to swap them, and see what happens.
     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    thanks Campbell

    I have been doing a lot of reading and in my opinion I believe the wildcard is pretty pointless,whats the point of using a wildcard you can't do much with it like add stuff to lists if the type is unknown that will give you a compilation error

    so instead of this


    why not just do this

     
    Adam Chalkley
    Ranch Hand
    Posts: 257
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    also whats the point of doing this



    if you just get a compilation error when you try to add something?
     
    Campbell Ritchie
    Sheriff
    Posts: 54495
    150
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    General rough rule of thumb, which I am sure Henry has already told you.
    If you have List<? extends Foo> you can get things out of it and be confident you can use them as a Foo. That means, “Whatever is in this List will be a Foo. It might be a subtype of Foo, but I don't know that. It won't matter, anyway.”
    If you have a List<? super Foo> you can take things which you are confident are a supertype of Foo and put them in it. That means, “If you add a Foo to this List, I can be sure it will fit in. You can also insert a supertype of Foo, but I don't know which type. It won't matter, anyway.”

    ? extends→remove. Don't add
    ? super→insert. Don't remove.

    I don't think your example with T extends E will compile. I agree: there probably is no point in trying to turn a List<Foo> into a List<? extends Foo>. Whoever told you about boxes for puppies (maybe Stephan?) showed you why you can't add anything to the List<? extends T>.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!