Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Problem with Generics Wildcard

 
Sudhanshu Gupta
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just saw this question in the self test of SCJP book's Generics chapter.
I wrote a code to verify it.




There were 3 options marked correct in the answers. I've tried all three in the code above.
The explanations given about them seem logical. But wen actually tried, they all cause compiler errors.

D:\Java Programs>javac GenericDemo.java
GenericDemo.java:14: incompatible types
found : java.util.List<capture#865 of ? super java.lang.Integer>
required: java.util.List<java.lang.Integer>
output = process(input);
^
GenericDemo.java:18: incompatible types
found : java.util.List<capture#671 of ? super java.lang.Integer>
required: java.util.List<java.lang.Integer>
output1 = process(input1);
^
GenericDemo.java:22: incompatible types
found : java.util.List<capture#402 of ? super java.lang.Number>
required: java.util.List<java.lang.Number>
output2 = process(input2);
^
3 errors



I just dont understand what seems to be the problem.
please help.
 
Henry Wong
author
Marshal
Pie
Posts: 20902
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There were 3 options marked correct in the answers. I've tried all three in the code above.
The explanations given about them seem logical. But wen actually tried, they all cause compiler errors.


First, you need to give more details about the source -- just which book you are referring to?

Second, you need to give more details about the question, as all three are indeed compile errors.

I just dont understand what seems to be the problem.


In all three cases, it is the assignment -- the value returned by the method can't be implicitedly assigned to the reference provided.

Henry
 
Rob Spoor
Sheriff
Pie
Posts: 20495
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
There were 3 options marked correct in the answers. I've tried all three in the code above.
The explanations given about them seem logical. But wen actually tried, they all cause compiler errors.


First, you need to give more details about the source -- just which book you are referring to?

I believe it is the Sierra / Bates SCJP 6 study guide. I have that (not here though) and I definitely recognize the question.

Sudhanshu, Henry does have a point. Please quote your sources. Could you please also include the answers themselves?
 
Sudhanshu Gupta
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi again

You are right Rob. This question is in Sierra / Bates SCJP 6 study guide.

The exact 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;
List<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.



and the answer was...


Answer:
B, E, and F are correct.

The return type of process is definitely declared as a List, not an ArrayList, so A and D
are wrong. C is wrong because the return type evaluates to List<Integer>, and that can't
be assigned to a variable of type List<Number>. Of course all these would probably cause a
NullPointerException since the variables are still null—but the question only asked us
to get the code to compile.



I guess i am mistaken somewhere but cant figure out where.
please help.
 
Henry Wong
author
Marshal
Pie
Posts: 20902
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I guess i am mistaken somewhere but cant figure out where.
please help.


All three compile errors are valid compile errors -- meaning those three options should not compile.

Did you check to see if there is an errata for this questions?

Henry
 
Rob Spoor
Sheriff
Pie
Posts: 20495
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since this question is about the SCJP and one of its books, I'm moving this to the SCJP forum. Bert Bates himself is active there so you may get an answer from the master himself
 
Sudhanshu Gupta
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you very much Rob for moving the question to the right place.
Where do i check the errata for the questions?
Sorry i am new to this.
 
Salil Vverma
Ranch Hand
Posts: 257
Hibernate Oracle Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey Sudhanshu,

As you know that this is giving the compilation error, I hope your question is why is it giving the error and what are various options to get that corrected.

Reason of Error - As we know that compiler checks the the typesafety of assignment and java does implicit upcasting but requires us to do expilcit downcasting. In this case as the return type process function is <? super E> . If we are passing the arugument as List<Integer> the posssible return type might be List<Integer> or List<Number> or List<Object> so definitely there are high chances of downcasting. That is why compiler gives us error to cast it explicitly. I believe, the below code would make the things more clear.



Resolution - - There are two ways we can resolve the error, the exact one that we should choose would depend on type of requirement

Solution -1 - Type cast the resut - As mentioned in the below code


Solution -2 - Define the outout variable to be of same type as of return type - As mentioned in the below code



I hope this would clear all of your confusions..
 
Sudhanshu Gupta
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Salil
thank you very much for the solutions.
It helped me understand the concept better.
However, My actual problem is something else.

If you refer to my earlier posts in this thread,

hi again

You are right Rob. This question is in Sierra / Bates SCJP 6 study guide.

The exact 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;
List<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.





and the answer was...


Answer:
B, E, and F are correct.

The return type of process is definitely declared as a List, not an ArrayList, so A and D
are wrong. C is wrong because the return type evaluates to List<Integer>, and that can't
be assigned to a variable of type List<Number>. Of course all these would probably cause a
NullPointerException since the variables are still null—but the question only asked us
to get the code to compile.





I guess i am mistaken somewhere but cant figure out where.
please help.


I found this question in the Self Test Section of SCJP Study Guide By Siera Bates.
There were 3 correct options given in the answer to the question.
To verify I wrote a sample code and tried all the options.


But to my surprise, All of them resulted in compiler errors.

D:\Java Programs>javac GenericDemo.java
GenericDemo.java:14: incompatible types
found : java.util.List<capture#865 of ? super java.lang.Integer>
required: java.util.List<java.lang.Integer>
output = process(input);
^
GenericDemo.java:18: incompatible types
found : java.util.List<capture#671 of ? super java.lang.Integer>
required: java.util.List<java.lang.Integer>
output1 = process(input1);
^
GenericDemo.java:22: incompatible types
found : java.util.List<capture#402 of ? super java.lang.Number>
required: java.util.List<java.lang.Number>
output2 = process(input2);
^
3 errors



So you see the your 1st Solution to typecast doesnot apply here.
Neither does your 2nd options of keeping the output variable of same type as the return type
as they are not in the options.


I am sorry if i annoyed you posting things all over again.
I just wanted to make sure that the experts here understand my problem better.
Thank you all for helping me.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic