[Lion{}, Tiger{}, BigCat{}]
Anil Philip wrote:I thought I understood the concept... but I guess, not.
I thought that
is immutable ensures that only one type of cat will be in the list. To prevent dissimilar subtypes in the list.
Paul Clapham wrote:
Anil Philip wrote:I thought I understood the concept... but I guess, not.
I thought that
is immutable ensures that only one type of cat will be in the list. To prevent dissimilar subtypes in the list.
It doesn't mean that at all. What it means is that the List which is assigned to the variable of type List<? extends BigCat> is in fact of type List<X> for some specific type X which extends BigCat.
In this case X is BigCat itself. So all elements in the List are of type BigCat, as you can see, and you have a List<BigCat>. It's true that some of them are elements of a strict subtype of BigCat, but that doesn't matter.
Anil Philip wrote:But why is the list immutable?
Javadoc wrote:Returns a fixed-size list backed by the specified array. Changes made to the array will be visible in the returned list, and changes made to the list will be visible in the array. The returned list is Serializable and implements RandomAccess.
The returned list implements the optional Collection methods, except those that would change the size of the returned list. Those methods leave the list unchanged and throw UnsupportedOperationException.
Ron McLeod[url=https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Arrays.html#asList(T...) wrote:Arrays#asList[/url] creates a list which is backed by the provided array. The array size is fixed so you can not add or remove any elements.
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
.Paul Clapham wrote:So it can't let you add a Lion object to the list because X might turn out to be Tiger at run time. Likewise for any subclass of BigCat.
Ron McLeod wrote:
Anil Philip wrote:But why is the list immutable?
I didn't see anything in your example code which showed immutability.
Rob Spoor wrote:... As for the immutability - although you cannot add any objects to a List<? extends T>, you can indeed add null, and you can also remove elements. In other words, the extends wildcard never ensures immutability.
Paul Anilprem wrote:>Which exact subclass of BigCat, it doesn't know. Since the compiler has no information about the actual List, it doesn't let you add anything to it using that variable.
[Lion{}, Tiger{}, BigCat{}]
Anil Philip wrote:
Paul Anilprem wrote:>Which exact subclass of BigCat, it doesn't know. Since the compiler has no information about the actual List, it doesn't let you add anything to it using that variable.
From your statement (if I understood you correctly), you are assuming that every element in the list is the same subtype.
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Paul Anilprem wrote:
No, I am not making any assumption about what the list actually contains. Which statement of mine gave you that impression? In fact, I clearly wrote that the actual list object might have come from elsewhere and might contain anything.
[Lion{}, Tiger{}, BigCat{}]
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
<br />Paul Anilprem wrote:
Which exact subclass of BigCat, it doesn't know. Since the compiler has no information about the actual List,
.....
This is very different from List<? extends BigCats<). This is not a list of BigCats. It is a list of some specific (but unknown to compiler) subclass of BigCats.
Anil Philip wrote:Or when it sees
and somewhere else,
It should know we are adding a Lion, which is a subtype of BigCat.
Paul Clapham wrote:
You surely don't mean to suggest that the compiler will resolve the type of the "list" variable by scanning the entire program to see where elements might be added to the list? It needs to assign the type by looking at that line of code only. And no, we've already been through this, List<? extends BigCat> is not the same as List<BigCat>.
Paul Clapham wrote:Did you compile those code samples you originally posted? I have a feeling many of them won't compile correctly.
Anil Philip wrote:
The compiler will look at the "add()" and verify it is a type of BigCat.
When it looks at the declaration of the list, it will determine what kind of list. Please see my post again.
Since the compiler has no information about the actual List, it doesn't let you add anything to it using that variable.
The actual list object might have come from elsewhere and might contain anything, But that is immaterial because the compiler's view is filtered by the variable definition.
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Anil Philip wrote:
I think there is a miscommunication.
The compiler will look at the "add()" and verify it is a type of BigCat.
When it looks at the declaration of the list, it will determine what kind of list. Please see my post again.
Paul Clapham wrote:
You could have considered trying that to see if it works; you will find thatas the next line of code does not compile.
Henry Wong wrote: Also, just because you can figure it out in your example, it doesn't mean that the specification can be done to allow the compiler to figure it out in all cases. For example, what if you changed the assignment to a method parameter? In that case, you won't be able to figure out the original type -- so, how do you expect the compiler to figure it out?
Henry
[Lion{}, Tiger{}, BigCat{}]
[Lion{}, Lion{}, Lion{}]
Paul Anilprem wrote:the compiler... has no idea about the actual object pointed to by the variable
Mike Simmons wrote:The compiler does have some idea, yes. But it doesn't know the actual types that will occur.
It's probably best not to use the word "immutable" to refer to something like List<? extends BigCat>
Paul Clapham wrote:The "actual type" which is passed is known only to the caller.
Anil Philip wrote:Even if it is a call into a library method, to my understanding, the types will be examined at compile time to see if the signatures match.
Paul Anilprem wrote:Generics is compile time magic only.
Mike Simmons wrote:
Anil Philip wrote:Even if it is a call into a library method, to my understanding, the types will be examined at compile time to see if the signatures match.
It will only be checked inside the new code that called it - it won't recompile the library method with information about its new callers. With processList(List<? extends Player>), inside that method it knows only that the argument is a List of some type of Player. That code might be compiled long before any outside code tries to call it. Maybe in one place, someone will call it with a List<CardPlayer>. And in another place, someone might call it with a List<PokerPlayer> (a type of cardPlayer). And somewhere else, they might call it with a List<BasketBallPlayer>, a different Player subtype which is unrelated to CardPlayer. So, inside the processList() method, what do we know about the type of the list? It could be any of those, or also any other type of List<? extends Player> which someone adds later on. The actual types of the objects in the list will always be some type of Player (well, unless someone deliberately miscasts a raw type) but it may be something more specific, or not.
As for "immutable", yes I would say that it's wrong of them to use it in the book. It just creates confusion here.
Paul Clapham wrote:
[code=java]
Anil Philip wrote:Sorry but that is incorrect, from what I understand.
A List<Lion> is not a List<BigCat>
In fact those two lines of code do not compile at all.
Anil Philip wrote:Which is why I was trying to understand what the issue is in allowing adds to the List as long as one is adding a kind of Player.
Anil Philip wrote:
<br />Paul Anilprem wrote:
Which exact subclass of BigCat, it doesn't know. Since the compiler has no information about the actual List,
.....
This is very different from List<? extends BigCats<). This is not a list of BigCats. It is a list of some specific (but unknown to compiler) subclass of BigCats.
The statements above are where I have the problem in understanding.
The compiler knows what you are adding to the list and whether it is a legal subtype.
Hence it should allow adds()
When the compiler sees
It should know this is a list of subtype Lion.
...
Enthuware - Best Mock Exams and Questions for Oracle Java Certifications
Quality Guaranteed - Pass or Full Refund!
Your buns are mine! But you can have this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
|