Forums Register Login

Generics doubt

+Pie Number of slices to send: Send
Hi,
I want to konw that is it true that we cannot add any element to a Collection whose generic signature is like this:

List l<? extends Object>=new List<? extends Object>
Or
List l<? Super String>=new List<? Super String>
Or
List l<?>=newList<?>

Can we ever use add method on such collections that return true?
I mean
l.add(o);
+Pie Number of slices to send: Send
Sandy,

This is an excellent tutorial for learning about Generics:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
+Pie Number of slices to send: Send
Well, you cannot write new List <anything>() because List is an interface.
+Pie Number of slices to send: Send
Right Barry
ok..Lets make it:
List l<? extends Object>=new LinkedList<? extends Object>
Or
List l<? Super String>=new LinkedList<? Super String>
Or
List l<?>=new LinkedList<?>
Now Can I say that whenever we use ? in generics, we can never add a new element in that?
Thanks
+Pie Number of slices to send: Send
You cannot do any of those either, you cannot instantate a class with a wildcard actual type parameter. So new LinkedList<?> is a nono, for example.
+Pie Number of slices to send: Send
Ok Barry Again My mistake.
Have a look at this code:

(I hope this is fine now)

So this code give me the following error:
---------------------------------------------
test62.java:7: cannot find symbol
symbol : method add(java.lang.String)
location: interface java.util.List<capture of ?>
l.add("Test");
^
1 error
---------------------------------------------

So shall I infer that we CANNOT add any element if a Collection is declared with '?' (but may be instantiated with some object)

Thanks for correcting
+Pie Number of slices to send: Send
With Eclipse 3.1.1 I get the compilation error: "The method add(capture-of ?) in the type List<capture-of ?> is not applicable for the arguments (String)" for the add line. Sort of gobbledegook message, isn't it?

However, in section 11.4 of "The Java programming Language, 4th Edition" it says:


Wildcards represent an unknown type, but whenever a variable that has a wildcard type is used, the compiler must treat it as having some specific type so that it can check for correct usage. This specific (but still unknown) type is referred to as the capture of the wildcard. The place you will most commonly come across the capture of a wildcard is in the error messages the compiler produces when you use a parameterized type the wrong way. For example, recall the incorrect attempt to add a String object to a queue accessed through an unbounded wildcard reference:

SingleLinkQueue<?> strings =
new SingleLinkQueue<String>();
strings.add("Hello"); // INVALID: won't compile


The error message this produced from the compiler we used was:

add(capture of ?) in SingleLinkQueue<capture of ?> cannot be applied to (java.lang.String)


This is telling us that when the wildcard reference strings is used, the type of queue is SingleLinkQueue<captureof ?>, so the type of the parameter to add is also "captureof ?". Because String is not compatible with "captureof ?" the call is not allowed.
<snip>
If a wildcard is always represented by its capture, it would seem that once you have a wildcard type you can only use it wherever a wildcard type is expected. Indeed this is a basic rule that ensures the integrity of the type system.

 
+Pie Number of slices to send: Send
Take a look at this method:



If this compiled (it gives the same compile error as above), then we could call the method like this:


and, on some days, end up with the wrong kind of element in the list myList.
[ October 13, 2005: Message edited by: Barry Gaunt ]
+Pie Number of slices to send: Send
One easy way (I think) to learn this is by seeing if the code can be misused in any way or not i.e if there is a possibility that the reference of the generic type can allow type unsafe operations, then it is probably not correct.

consider
List<?> list= new LinkedList<String>();

now just consider what types of operations might breach the type homogenity.
remember, when we have something like this, we must consider the case where nothing about the reference can be known at "compile" time.

so, the best thing to do is, to see what might happen when the reference is passed as an argument-

so assume we have

List<String> ls==....//whatever it is, we're not concerned
and then we call
operationU(ls);

and we have
void operationU(List<?> lu){
//area 1
}

now given the above,
lets see what are the type-safe operations possible in "area 1"

Q1. Can we lu.add("hi"); ?
A. If we could, then it would be possible to do lu.add(new Integer(4)); also
which would clearly break the type homogenity. wouldn't it?
therefore, we can conclude that lu.add(/*anything*/) is not permissible

Q2. Can we lu.get(1)?
A. why not? is there any way it tampers with the type of data in lu?

so, the conclusion I usually get to, is that with generic types which are the captures os ? i.e Collection<?> etc, only non-destructive operations are permitted, i.e the no data is modified in the reference, only accessing is permitted. Atleast, thats the way I work

You may now ask, why
if it were
void operationU(List <? extends A> les){
//area 2
}
les.add(/*some object passable as A*/); is permitted?
Simple, the compiler treats les as List of "A" objects, so even if you put an object of B extends A, it will treat it as an object of A, and not B

but also keep in mind that, after type erasure, both the versions of operationU will look like this
operationU(List){

}

I'm developing on this approach, so if you find any flaws, kindly feel free to post it or send me a message,
thanks
+Pie Number of slices to send: Send
Thanks for such an informative explination Akshay.

So I think I should conclude wherever I find a collection declared as captures of ? that means that the Collection is read only..or in other words calling add will not be safe on such a generic collection.

Fine I think.
I love a woman who dresses in stainless steel ... and carries tiny ads:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 1060 times.
Similar Threads
Generics From John Meyer Mock (? super String)
Doubt in Generics
Question from mock exam
one more doubt abt generics
generic - ? super...
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 04:26:20.