• 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

 
Ranch Hand
Posts: 34
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Source : http://www.etattva.com/


The explaination says :
Does not compile at 2. List<T> is required. Can not convert ArrayList<String> to List<T>

Can someone explain
 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You cannot use the wildcard ? when declaring collections.

K&B book says clearly that it is not legal.

think about, what would be if you have the following "for" loop inside the method.



I hope this helps you.
<><

[ December 29, 2008: Message edited by: Djonatah Stiegler ]
[ December 29, 2008: Message edited by: Djonatah Stiegler ]
 
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Djonatah Stiegler:
You cannot use the wildcard ? when declaring collections.



He is not declaring a collection with a wildcard, he just declared a method that accepts list<?> as parameter.

Originally posted by Sharma Shweta:

The explaination says :
Does not compile at 2. List<T> is required. Can not convert ArrayList<String> to List<T>



You declare that the function returns a List of type T but you are trying to return a List of type String.

It should be something like this:
 
Djonatah Stiegler
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm sorry I was wrong,

I didn't see I was stupid.. you are right , you can receive a List<?>...

Sorry for that
 
Ranch Hand
Posts: 952
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Sharma Shweta:
Source : http://www.etattva.com/


The explaination says :
Does not compile at 2. List<T> is required. Can not convert ArrayList<String> to List<T>

Can someone explain



Your method return type is List<T>.
So you should think what are the valid options assignable to List<T> reference.

like:
1. List<T> list=new ArrayList<T>();//valid

2. List<T> list=new ArrayList();//valid

3. List<T> assignList=new ArrayList<T>();
List<T> list=assignList;//valid

4. List assignList1=new ArrayList<T>();
List<T> list=assignList1;//valid

5. List<T> assignList2=new ArrayList();
List<T> list=assignList2;//valid

6. List<T> list=new ArrayList<String>();//invalid, generics parameter should not differ

7. List<T> list=new ArrayList<Object>();//invalid, generics parameter should not differ

so your method could return any of above valid options.


public <T> List<T> meth(List<?> type)
{
System.out.println(type); // 1

return new ArrayList<T>();//ok 1

//return new ArrayList(); //ok 2

//List<T> assignList=new ArrayList<T>();
//return assignList;//ok 3


//List assignList1=new ArrayList<T>();
//return List<T> list=assignList1;//ok 4

//List<T> assignList2=new ArrayList();
//return assignList2;//ok 5

}

 
Shwetha Sharma
Ranch Hand
Posts: 34
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Punit for for the explaination
I am finding generics as the most difficult part of the exam.
Well one more question

It is giving compile time error saying that
found : java.Util.List<java.lang.Integer>
required : java.Util.List<T>

Why is this error coming as we have already defined T as T extends Number, so this method can return any List of object of a class which is subclass of Number
 
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
T is supposed to be a sub-class of Number. But the method itself cannot decide what T actually is. This will be decided by the call to the method

If you call the method as

List<Integer> list = obj.meth(new ArrayList());

Then T will represent Integer. But if you call the method like this

List<Byte> list = obj.meth(new ArrayList());

Then T will represent Byte. So the call to the method will decide what T represents. You cannot decide this in the method itself...
 
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Shweta the List<?> as argument to meth() does not really help you use the power of generics.
First of all you could send List<String> type object to the method.
Secondly, you won't know inside the method what you are getting in the argument.
Thirdly, you can't add anything to the List<T> list1 as list1.add() takes an argument of type T which is decided at compile time.

Moreover, Ankit i don't think that in the following statement

List<Byte> list = obj.meth(new ArrayList());

you are actually deciding what type <T> is. Actually you could do the following with misleading type info.




Please correct me if i am wrong.
[ January 02, 2009: Message edited by: Harvinder Thakur ]
 
Ankit Garg
Sheriff
Posts: 9707
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As far as I know, call to the method will decide the type of T. It is another matter that you can trick the generics mechanism like you gave the example. I didn't try to compile your program but I think it will give a warning at

List<T> list1 = new ArrayList();

So basically if you get a runtime exception, then the compiler is not responsible as it had warned you.

Moreover if the call would not decide the type of T, then the call would fail. If I call

List<Byte> list = obj.meth(new ArrayList());

and if you say that T would not represent Byte, then can you tell me what T would represent. Suppose T would represent Number, then the assignment would look like this

List<Byte> list = new List<Number>();

and this would fail to compile as you cannot assign a Number list to a Byte list. Not even Number, if the type of T is not Byte, then assignment would fail for any type other than Byte. I mean to say that List<Byte> can only be assigned a List of type Byte and nothing else.

So finally I would say that the call decides the type of T as T is only in the return clause. I may be wrong as I am not a Guru or something...
 
Punit Singh
Ranch Hand
Posts: 952
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


public <T extends Number> List<T> meth(List<?> type)
{
System.out.println(type); // 1
List<Integer> list1 = new ArrayList();
return list1;
}



You are doing this thing here:
List<T extends Number> list=new ArrayList<Integer>();

So compiler does not know here what could be T in <T extends Number>, it could be Byte, Short, Long, Float, Double. If this was allowed than there is no runtime checking or runtime generics info that will stop you from adding Double value in a Integer list.

If you know ArrayStoreException, and why ArrayStoreException happen? you will understand it quickly. ArrayStoreException is runtime checking with array that determines Integer[] cannot contain Double value, but for generics there is no such equivalent runtime checking, so compiler detects this type of situation and avoids you from doing these things.

If you think like compiler here, you can understand it more comprehensively.
 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let us first discuss whether a List<Byte> IS-A List<Number>. The code

is correct if x is a List<Number>, but not if x is a List<Byte>. Thats why, List<Byte> not IS-A List<Number>.

For the moment, we ignore the implementation of meth by return null, which is always possible, but include T in the parameter definition:

meth compiles fine. When the compiler tries to compile one of the lines in main, it tries to map T to a type so that the arguments match and the bound T extends Number is satisfied. In line 5 this is impossible, so this line fails to compile, even without an assignment. In lines 1 and 3 T maps to Byte, in lines 2 and 4 T maps to Number. But since the return type of meth is List<T>, the right hand side in line 2 is now List<Number>, which cannot assigned to a List<Byte>. Similarly, line 3 fails. Lines 1 and 4 compile.

If we change the method definition to

the arguments do not restrict T, and the compiler map T to make the assignments possible: T maps to Byte in lines 1 and 2, T maps to Number in lines 3 and 4. All lines in main compile.

Anything we write instaed of line 0 must play with all possible mappings for T. At the time of compiling meth, only T extends Number is known. So

fails, since it not IS-A List<T> if T is mapped to Byte, and

fails, since it not IS-A List<T> if T is mapped to Number. Ok is

If we change the return type, things become interesting, the following compiles (but the lines in main must change too):

On my exam, there where no such weird questions on generics. It is more important to be completly clear with object orientation, leaving generics aside for a moment. What can a variable assigned to? What can a method return? (Hint: there are a lot of IS-A in the answers.) Combining this with what i said about IS-A above was enough.
 
Shwetha Sharma
Ranch Hand
Posts: 34
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks John for the informative explaination.
 
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
John...to clarify your final example....................



In this case we can specify:
2. return new ArrayList<Number>();

rather than
2. return new ArrayList<T>();

Is this because Number is the only class that satisfies both <T extends Number> and <? super T> so, there is no ambiguity at compile time as to what
T could be?. While in the prior examples (without the <T extends Number> and <? super T> combination), T could not be known at compile time so the return statement had to return List<T> rather than List<Number> ?

 
John Grabowsky
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear Patrick,

It is not necessary that ONLY Number satisfies both <T extends Number> and <? super T>, btw the following compiles too:

The point is that for every T satisfying <T extends Number>, the generic type we try to return must satisfy <? super T>, which are Object, Number, and T.

T is not known at compile time here (can be Number, Byte, ...), the difference is that T is bounded. If the extends Number is removed, we can return only generic types that satisfy <? super T> for any T, that is Object and T. If, in addition, the ? super is removed (now we are back to Shweta's initial example), we return only generic types equal to T for any choice of T, so T itself is our only choice.
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Grabowsky wrote:
T is not known at compile time here (can be Number, Byte, ...), the difference is that T is bounded. If the extends Number is removed, we can return only generic types that satisfy <? super T> for any T, that is Object and T. If, in addition, the ? super is removed (now we are back to Shweta's initial example), we return only generic types equal to T for any choice of T, so T itself is our only choice.


EDIT: I saw the flaw in my reasoning, please disregard my question. The exact value of T is not known at compile time, so the only types that we can return when the return type is List<? super T> will be List<T> and List<Object>, since every type is of type Object. It's interesting that, because of the compile-time nature of generics, in this case adding more information results in more choices for possible return types.

Hi John,

Thanks for explaining all this in such detail. I have a question about your statement set to bold above. How can removing <T extends Number> make the return type more restrictive? I think it would actually make it less restrictive. For example, T is Byte, the return could still be Byte, Number or Object. And if it were any type with 3 ancestor classes instead of two, then you would have 4 possible return types. Am I missing something maybe?

Thanks in advance for your input.
 
John Grabowsky
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ruben,

i see you analyse thoroughly, interesting discussion. Can you find any return statement that compiles when the signature is

but not when

? I think the point is: the return statement must work with any possible match of T. The more matches for T, the more restricted the legal return statements. Or, said the othe way around, restricting T makes more return statements possible.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
John,

That's a very precise and insightful way to put it, thanks for explaining.
 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,
I am preparing for SCJP1.5 finding generics to be tough and a bit confusing.
Source: Kethy and Bates CD question.

import java.util.*;
public class BackLister{

//Insert code here

{
List<T> output= new linkedList<T>();
for (T t:input)
output.add(0,T);
return output;
}
}

Which of the following can be inserted at // Insert here.
1) public static <T> List <T>backwards ( List <T> input)
2) public static <T> List <T> backwards ( List <? extends T> input)
3) public static <T> List <T> backwards ( List <? super T> input)
4) public static <T> List <? extends T> backwards (List <T> input)
5) public static <T> List <? super T> backwards ( List <T> input)
6) public static <? extends T> List <T> backwards ( List <T> input)


Answer is : ABDE

not clear with the exact declaration syntax for Generics and how to use wildcards -extends and super in the above problem.

If anyone can help me , it will be great. Thanks in advance.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Edited
I see Pooja already started a new thread for this question.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic