• 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

generics / adding to wildcard Collection

 
Ranch Hand
Posts: 90
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello, I'm puzzled how the "adding" to wildcard java.util.Collection is blocked by the compiler; compiler even suggests that "add"-method doesn't exist. Also how is this different to "putting" element to custom wildcard object.

For example,
Following attempt will produce following compiler error "cannot find symbol / symbol : method add(java.lang.String) / location: interface java.util.List<capture#913 of ? extends java.lang.String>"


while following code (modified example from http://www.ibm.com/developerworks/java/library/j-jtp04298/)

produces compiling error that "put(capture#189 of ? extends T) in OtherBox<capture#189 of ? extends T> cannot be applied to (java.lang.String) box.put("blaa");"

It *seems* that compiler adds some check for Collection add and addAll methods, but surely that can't be true?
 
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
An obvious error that I see is not using "super" keyword when adding to the list. Go back to Chapter 7 on Generic Methods (Exam Objectives 6.3 and 6.4) for more info and to reinforce your knowledge.

Try this:



 
Tapio Niemela
Ranch Hand
Posts: 90
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tommy and thanks for reply

Yes, I know about the lower bounds, but I was distracted by the different compile errors. Handling wildcards with java.util.List (like trying to add to wildcard-List) generates (at least on my 1.6.0 compiler) different compile error than with the Box-example. With List I get "cannot find symbol" and with "Box"-example I get "cannot be applied" to -error. This really puzzled me. The thing is that if I use Collection.add I get also "cannot be applied"-error, not "cannot find symbol", so I should get "Cannot find symbol" error with modified OtherBox as I do..



So the problem was the distraction from different compile error messages created by my compiler
 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Think about it this way, if you have an animal class and a dog and cat class that extends animal. And you have a method that accepts <? extends animal>, this is saying you could pass anything that is a subclass of the class animal into this method. Now say that you have a dog collection and you pass that dog collection into the method, and in that method you try and add a cat.. now you have a collection of dogs and cats in the dog collection. To prevent this the compiler will not allow adding to the collection using the extend keyword.
 
Tommy Delson
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So the problem was the distraction from different compile error messages created by my compiler



Yes, different Compiler gives you different error message, but the point here is when you using Generics and Collections in such cases you need to use "super" to add or put object in the List or Map, and the "extends" keyword is work fine with getting objects out of the List or Map.

Have you reread the Chapter section that I mentioned in the previous post? If not, I recommended to reread the section several times until you clear the concept.

Hope it help...
 
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Suppose you have a class Node :


And suppose you have another class Foo:

1 . What should be put in the n.set() as parameter? It must be null, nothing else.
Reason:
The compiler does not know what the paremter type n can accept. It can be Integer, Double.... What if n takes an Integer type as the E and then you set this.e to a Double? For this reason, the compiler won't let you pass in any object type paremeter to the set method. It applies to all other situation similar to this example.

2. What should be return from n.get() ? It must be Number. Therefore, you can assign Number aNum= n.get(); where aNum is a null.
Reason:
The compiler only knows n takes a Number type. This is the only information it knows.

3. What should be put in the n1.set() as parameter? It must be some types that are Number or its subtype.
Reason:
If n1 accepts E as a Number and you pass in an Integer as the parameter , it will be setting the E e ( E is substituted by Number) to an Integer. That is ok. If you pass in an Object as the parameter, it will be setting the Number e = new Object(); That won't compile at all. For this reason, the compiler won't let you pass in any type that is the super type of Number.

4. What should be return from n1.get()? It must be Object. Therefore you can assign Object o = n1.get();
Reason:
For case 3, you can only set e of the Node class to be a Number, Double, Integer....(subtypes). For sure, the compiler knows you pass in a Number. Why can't we assign Number myNum = n1.get()? Because you may assign the n1 to a node that takes Object like this:

The compiler only knows n1 takes a Number or an object, but it does not know what exactly it is. The safest return type for the get() is only an object.

Thefore, when you are given any class (Node, List....) with generic parameters, a method that takes the generic parameter as argument and a method that returns the object of the generic parameter type, you will think of the above 4 cases.
This is an example from Mughal and Rasmussen's study guide , chapter 13 Generics.

Summary:
What to put for set's parameter:
Node<? extends Number> Node<? super Number>
set Null Number or its subtype

What to return for get method:
Node<? extends Number> Node<? super Number>
get Number or Object Object only

 
Ranch Hand
Posts: 88
Netbeans IDE Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Helen Ma wrote:
2. What should be return from n.get() ? It must be Number. Therefore, you can assign Number aNum= n.get(); where aNum is a null.
Reason:
The compiler only knows n takes a Number type. This is the only information it knows.



Actually, it does not _have_ to be Number, it can be a supertype of Number and it will work just fine.

For example, I could do this: Serializable aSer = n.get(); and it works just fine.
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
please explain me why the code will compile(example given in kathy sierra for scjp 5)

punlic class TestWildcards
{
public static void main(String [] args)
{
List<Integer> mylist =new ArrayList<Integer>();
Bar bar= new Bar();
bar.doInsert(mylist);
}
}



class Bar
{
void doInsert(List<Object> list)
{
list.add(new Dog());
}
}


Dog is a class defined in other examples...
it should give compilation error
 
Mack Wilmot
Ranch Hand
Posts: 88
Netbeans IDE Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

neha chaukar wrote:please explain me why the code will compile(example given in kathy sierra for scjp 5)

<snip>



It doesn't compile.
 
neha chaukar
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yeah that is what i think.But in book it given that it will compile..
anyways thanks ..
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

neha chaukar wrote:yeah that is what i think.But in book it given that it will compile..


The book doesn't say it will compile. It says Bar will compile, but there's a problem with TestWildcards.
 
Bartender
Posts: 2418
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
List<Object> cannot refer to List<Integer> even though Integer is an object.
For example List<Object> objectList = new ArrayList<Integer>(); won't compile.

 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic