aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes I have doubt in a question in Generics(Q16) SCJP5 K&B book Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "I have doubt in a question in Generics(Q16) SCJP5 K&B book" Watch "I have doubt in a question in Generics(Q16) SCJP5 K&B book" New topic
Author

I have doubt in a question in Generics(Q16) SCJP5 K&B book

ganesh kannan
Greenhorn

Joined: Jan 17, 2009
Posts: 7
Hi all,
I have joined JavaRanch today. Hope you all would help me become a good java cowboy!
I am preparing for SCJP5.0 and im using K&B SCJP5 book. I am not clear about a question in Generics(Q16).The question is:

Given a method declared as public static <E extends Number> List<? super E> process(List<E> nums)
A programmer wants to use this method like this:

//INSERT DECLARATIONS HERE
output=process(input)

Which pairs of declarations could be placed at //INSERT DECLARATIONS HERE to allow the code to compile(Choose all that apply.)
A ArrayList<Integer> input = null;
ArrayList<Integer> output = null;

B ArrayList<Integer> input = null;
List<Integer> output = null;

C ArrayList<Integer> input = null;
ArrayList<Number> output = null;

D List<Number> input = null;
ArrayList<Integer> output = null;

E List<Number> input = null;
List<Number> output = null;

F List<Integer> input = null;
List<Integer> output = null;

G None of the above

Could you please check the answer with proper explanation (easy to understan huh! :wink

Thanks in advance
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9313
    
  17

Hi Ganesh! Welcome to javaranch.

Let me explain the method declaration to you and then you tell me if you have any doubts

<E extends Number> List<? super E> process(List<E> nums)

Now in this the first part i.e. <E extends Number> is declaring a type for this method with the name E. It is a constraint here that E must be of type Number or a sub-class of Number like Integer, Long, Double etc. Now the return type of the method id List<? super E>. This means that the method will return a List whose type will be E or a super type of E. This means that if E is Integer, then the method can return List<Integer> or List<Number> or List<Object> or a List of any other super type of Integer. And if E is Number, then the method can return List<Number> or List<Object> or a List of any other super type of Number like List<Serializable> etc. Lastly the method will be passed a list of type E. This is the actual part which will decide what E actually is. So if you pass the method List<Integer> then E will represent Integer and if you pass the method List<Number>, then E will represent Number. Now according to this validate all the options and tell me if you have any doubts...


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Yuan Du
Ranch Hand

Joined: Nov 20, 2008
Posts: 34
Hi Ankit,

I'm not really clear, why the return type of process must be a List, not ArrayList or LinkedList or something else, which inherits from List?

Okey, i think i got it. because List cannot be assigned to ArrayList or LinkedList. Am i right?

Yuan
Sachin Adat
Ranch Hand

Joined: Sep 03, 2007
Posts: 213
Yuan Du wrote:why the return type of process must be a List, not ArrayList or LinkedList or something else, which inherits from List?

A reference of List can take an ArrayList Object but not the other way round.


SCJP 6
How To Ask Questions On Java Ranch - How To Answer Questions On Java Ranch
Sachin Adat
Ranch Hand

Joined: Sep 03, 2007
Posts: 213
Yuan Du wrote:because List cannot be assigned to ArrayList or LinkedList. Am i right?
You are !!!
Yuan Du
Ranch Hand

Joined: Nov 20, 2008
Posts: 34
Ok, thank you Sachin.
ganesh kannan
Greenhorn

Joined: Jan 17, 2009
Posts: 7
Thanks a lot Ankit.

Yuan you can assign List to ArrayList using a cast

List<String> list = null;
ArrayList<String> a = null;
a =(ArrayList<String>)list;


I am writing SCJP5.0 on 24th Jan. Can anyone tell me whether the diddiculty level has crept in a litter more than 2008? or is it same as last year??
Maurice Le Chat
Greenhorn

Joined: Jan 20, 2009
Posts: 18
I would say the only correct answer to this question is:

G.) None of above.

The only way to compile a copy of this snippet within eclipse results in:

List<Integer> input = null;
List<? super Integer> output = null;

or

List<Integer> input = null;
List<? extens Number> output = null;

when the method call is changed to:

public static <E extends Number> List<? extends E> process(List<E> nums){

would be nice to hear opinions.

Maurice

SCJP 5
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9313
    
  17

Well I just checked it in my 6.0 book and the statement is this

public static <E extends Number> List<E> process(List<E> nums)

I don't know if this is an error in the 5.0 book or he wrote the wrong code here...
ganesh kannan
Greenhorn

Joined: Jan 17, 2009
Posts: 7
Hi Ankit,
I just rechecked it in my 5.0 book. Its same as what i typed(List<? super E>). So which is the correct answer? G.None of the above or B,E,F ? Could anyone give proper explanation for this? So it an error in the book??

Thanks,
Ganesh
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Maurice Le Chat wrote:I would say the only correct answer to this question is:

G.) None of above.

The only way to compile a copy of this snippet within eclipse results in:

List<Integer> input = null;
List<? super Integer> output = null;

or

List<Integer> input = null;
List<? extens Number> output = null;

when the method call is changed to:

public static <E extends Number> List<? extends E> process(List<E> nums){

would be nice to hear opinions.

Maurice

Hi Maurice,
I think that is correct. (Disclaimer: I'm still learning about generics, so some of the following might be wrong. If it is, I hope someone can make corrections.)

Let's look at the first one:

In this case, the method returns List<? super Integer>. That means that the compiler doesn't know anything about the actual generic type of the list returned, except that it must be Integer or a supertype of Integer. It could be List<Object>, for example.
If you tried to do
List<Object> output = null;
that might seem like a good idea, but it is not. Imagine what would happen if the actual type returned were List<Integer>. Now you have a reference of type List<Object> pointing to an instance of type List<Integer> and are free to corrupt the list by inserting things that don't pass the Is-A test for Integer.
Remember that List<? super Integer> will let you read an element of the list only into an Object reference, because you don't know the actual type of the elements, except for the fact that its lower bound is Integer and its upper bound is Object. Also, List<? super Integer> will let you add elements of type Integer or any of its subtypes. That's acceptable, because the type, although unknown, will pass the Is-A test for Integer and all its descendants.
You can look at it this way: The upper bound on the wildcard determines the lowest (in the class hierarchy) reference type you can assign an element to, whereas the lower bound on the wildcard determines the highest (in the class hierarchy) reference type of elements that you can add to the collection. (You also would need to consider interfaces, by the way, I'm simplifying the discussion by only talking about classes.)

The second case is:

In this case, the method returns List<? extends Integer>. The actual returned type could be List<Integer>, or List<X> where X is a subtype of Integer. The upper bound of the wildcard is Integer, but unfortunately there is no lower bound (I am qualifying this statement below with a peculiar exception.) Referring to our previous discussion, you can see that:
- Since the upper bound of the wildcard is Integer, that means that you could assign elements of the list to reference variables of type Integer or any of its supertypes.
- Since the lower bound does not exist, that means that you can not add elements of any type fo the list. Actually, there is an exception to this rule: You can add a null to it, because the null type is conceptually a descendant of every other class (the opposite of Object, which is an ancestor of every other class.) Don't get confused with this, this doesn't mean that Java supports multiple inheritance, it is just a special case.

If the return type of the method is List<? extends Integer>, you can only assign that to a List<? extends Integer> reference. Trying to do something like List<Integer> would fail (List<Integer> is not a supertype of List<X>, where X is a proper descendant of Integer.) The reason is the same reason why List<Object> is not a supertype of List<? super Integer>.

One last thing: You could get away in both cases using the raw type:

List output = null;
You might get warnings, but it should compile. I think you would only get warnings if you tried to add anything using the raw type though.

Please, let the corrections start coming in!


All code in my posts, unless a source is explicitly mentioned, is my own.
Punit Singh
Ranch Hand

Joined: Oct 16, 2008
Posts: 952
Ruben wrote: The upper bound on the wildcard determines the lowest (in the class hierarchy) reference type you can assign an element to, whereas the lower bound on the wildcard determines the highest (in the class hierarchy) reference type of elements that you can add to the collection. (You also would need to consider interfaces, by the way, I'm simplifying the discussion by only talking about classes.)


Here seems some gotcha to me: I think you have written opposite here by mistake

Upper bounded wildcard means:
List<? extends Number> list=null;

so this will determine highest reference type you can assign, that is Number



Lower bounded wildcard means:
List<? super Integer> list=null;

so this will determine lowest reference type you can assign, that is Integer



SCJP 6
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Good one Punit.
Actually I think that what I said is true too (because I was talking the possible reference types of objects that can be added to the collection, and about the possible reference types of variables that we can assign elements of the collection to.) But I missed a big part of the story, which is what you explained, because you are looking at it from the point of view of the collection type itself. And that brings some interesting points.

For upper bounded wildcards:
Collection<? extends X>: Here X is the upper bound on the type of the elements of the collection. There is no lower bound.
Here, we have that:
1. Based on the upper bound (X):
a. We can assign an element of the collection to a reference variable of type X, or of any of X's ancestors.
b. To a reference variable of type Collection<? extends X> we can assign a collection of the generic type X or any of X's descendants (Of course, the base type would need to be compatible also. I will not include the base type (in this case Collection) in the discussion from this point on.)

2. Based on the lower bound (no lower bound, except the null type):
a. We can not store an element of any type into the collection using this reference, except null (the only instance of the null type.)

3. You can not assign a reference of type Collection<? extends X> to a reference variable of any type, except Collection<? extends X>, Collection<?>, and Collection (the corresponding raw type.)

For lower bounded wildcards:
Collection<? super Y>: Here Y is the lower bound on the type of the elements of the collection. The upper bound is Object.
In this case:
1. Based on the upper bound (Object):
a. We can assign an element of the collection to only a reference variable of type Object.

2. Based on the lower bound (Y):
a. We can store elements of type Y and any descendants of Y into the collection using this reference.
b. To a reference variable of type Collection<? super Y> we can assign a collection of the generic type Y or any of Y's ancestors.

3. You can not assign a reference of type Collection<? super Y> to a reference variable of any type, except Collection<? super Y>, Collection<?>, and Collection (the corresponding raw type.)

That's it, I'm done with generics for the day. Again, I would appreciate if you can point out my errors.
Punit Singh
Ranch Hand

Joined: Oct 16, 2008
Posts: 952
Ruben Soto wrote: 1. Based on the upper bound (Object):
a. We can assign an element of the collection to only a reference variable of type Object.


What you want to say here?
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Punit Singh wrote:
Ruben Soto wrote: 1. Based on the upper bound (Object):
a. We can assign an element of the collection to only a reference variable of type Object.


What you want to say here?

What I mean is that if you have this:
List<? super Y> a = new ArrayList<Y>();
// Some code
Object o = a.get(0); // Can only assign element to an Object reference

Is this wrong? There is no knowledge about the type of the elements in a that the compiler can get from the reference type, since the element type is only bound upwards by Object.

Whereas if you have:
List<? extends X> b = new ArrayList<X>();
// Some code
X x = b.get(0); // You can do this, because the type has X as an upper bound
SuperOfX sx = b.get(0);
Punit Singh
Ranch Hand

Joined: Oct 16, 2008
Posts: 952
hmmm good, explain with examples, that will make things crystal clear, otherwise it will be like reading long books, as you write long long paragraphs
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
You are right Punit. I need to use more examples and less descriptions. Even the JLS has more examples than my posts. :lol:
Punit Singh
Ranch Hand

Joined: Oct 16, 2008
Posts: 952
Ruben Soto wrote:You are right Punit. I need to use more examples and less descriptions. Even the JLS has more examples than my posts. :lol:


You are doing lots of reading and research work. It seems you are going to design a new language. What about your SCJP, when will you give?
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Punit, I want to take my exam soon, maybe in the next few weeks. The problem is that the more I learn the more I realize I don't know, but I think you need to stop at some point and just go for it.
Prav sharma
Ranch Hand

Joined: Feb 07, 2005
Posts: 102
I went through same situation few days back. But finally i fixed a day and stuck to it.
Don't be scared. Just revise what you have practiced all these days.

Cheers !!!

Ruben Soto wrote:Punit, I want to take my exam soon, maybe in the next few weeks. The problem is that the more I learn the more I realize I don't know, but I think you need to stop at some point and just go for it.
Ruben Soto
Ranch Hand

Joined: Dec 16, 2008
Posts: 1032
Prav sharma wrote:I went through same situation few days back. But finally i fixed a day and stuck to it.
Don't be scared. Just revise what you have practiced all these days.

Cheers !!!

Ruben Soto wrote:Punit, I want to take my exam soon, maybe in the next few weeks. The problem is that the more I learn the more I realize I don't know, but I think you need to stop at some point and just go for it.

Thank you, Prav. I really have to do that. So how did things go for you? Did you find the exam reasonable?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: I have doubt in a question in Generics(Q16) SCJP5 K&B book