Java Forum / General / November 2005
generics question.
Amarnath B S - 28 Nov 2005 13:16 GMT Could anyone help me by explaining the behaviour below?
----------code snippet start-----------
static <T> void some( T a[], Collection<T> c){ //nothing } .... some(new Number[100], new ArrayList<Float>()); //compile time error some(new Float[100], new ArrayList<Number>());//allowed -----------code snippet end-------------
Why is the first method invocation not allowed? How does the compiler compare the type dependencies?
thanks in advance, Amarnath
Thomas Hawtin - 28 Nov 2005 14:10 GMT Amarnath B S wrote (in a different order):
> static <T> void some( T a[], Collection<T> c){ > //nothing > } > > Why is the first method invocation not allowed? How does the compiler > compare the type dependencies?
> some(new Number[100], new ArrayList<Float>()); //compile time error The second argument implies that T is Float. Number[] is not assignable to Float[].
> some(new Float[100], new ArrayList<Number>());//allowed The second argument implies that T is Number. Float[] is assignable to Number[].
Array types are quite eccentric. Best off sticking to collections.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Amarnath - 29 Nov 2005 09:19 GMT > Amarnath B S wrote (in a different order): > > [quoted text clipped - 21 lines] > Unemployed English Java programmer > http://jroller.com/page/tackline/ If that is the case, then static <T> void some(Collection<T> c, T a[]){ } ........ some(new ArrayList<Float>(), new Number[100]);
should compile well. But it doesn't !!
-Amarnath
Hendrik Maryns - 29 Nov 2005 10:43 GMT Amarnath schreef:
>>Amarnath B S wrote (in a different order): >> [quoted text clipped - 29 lines] > > should compile well. But it doesn't !! Read about arrays in the essay on generics. It is quite complex, and quite a nuisance, for instance, you cannot do something like
List<State>[] stateList = new List<State>[15];
Only
List<?>[] stateList = new List<?>[15];
or
List<State>[] stateList = new List[15]; (*)
are allowed, the first making it impossible to add anything to the lists and needing explicit casts when asking for one of the elements of the list, the second generating an "unchecked" warning. The reason is that generics are only in the compiler, and as arrays are also objects, they can be assigned to Object variables, which leads to all kinds of problems.
See http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf, section 7.3, but note that there is an error in there, specifically about the line (*). Also read the section about fun with wildcards, which will probably solve your problem above: you can write
static <T> void some(Collection<T> c, <? super T> a[]){ } ........ some(new ArrayList<Float>(), new Number[100]);
H.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Thomas Hawtin - 29 Nov 2005 17:35 GMT >>Amarnath B S wrote (in a different order): >> [quoted text clipped - 14 lines] >>The second argument implies that T is Number. Float[] is assignable to >>Number[].
> If that is the case, then > static <T> void some(Collection<T> c, T a[]){ [quoted text clipped - 3 lines] > > should compile well. But it doesn't !! I really don't follow your logic there at all. Applying my argument as above to this example:
The argument "new ArrayList<Float>()", of type ArrayList<Float>, implies that T is Float. The argument "new Number[100]", of type Number[], is not assignable to Float[].
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Roedy Green - 28 Nov 2005 16:41 GMT >static <T> void some( T a[], Collection<T> c){ > //nothing > } >.... >some(new Number[100], new ArrayList<Float>()); //compile time error >some(new Float[100], new ArrayList<Number>());//allowed If machines were sentient, I think this get you a jail term for compiler abuse.
I think the answer may become clear if in your call instead of relying on type inference you used an explicit type in the invocation.
Another hint. Try reversing the order of the parms to some.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Amarnath - 29 Nov 2005 09:17 GMT > >static <T> void some( T a[], Collection<T> c){ > > //nothing [quoted text clipped - 14 lines] > Canadian Mind Products, Roedy Green. > http://mindprod.com Java custom programming, consulting and coaching. Compiler abuse!! I was just trying to understand it!! Anyway.., Yes, I could have used explicit types, but I would like to understand the compiler's behaviour here.
static <T> void some(Collection<T> c, T a[]){ } ........ some(new ArrayList<Float>(), new Number[100]);
The above does not compile either.
-Amarnath
Brendan Guild - 29 Nov 2005 13:51 GMT > static <T> void some(Collection<T> c, T a[]){ > } > ........ > some(new ArrayList<Float>(), new Number[100]); > > The above does not compile either. Would you want it to compile? If I was writing a function some (Collection<T> c, T a[]), I would sure want to be able to put the elements of 'a' into 'c'. But how can I do that if 'a' is an array of all kinds of Numbers and 'c' can only hold Floats?
If you make it explicit that 'c' and 'a' hold the same kind of things, then why would you want to start putting something else in there?
Of course, arrays are a different thing than collections; arrays are more powerful and even a little dangerous. Float[] is a subtype of Number[], so you can pass in a Float[] where a Number[] is expected without complaint and everything works just right. That's why some(new ArrayList<Number>(), new Float[100]) would work, because it is expecting a Number[] but accepts a Float[]. If you try to put something from 'c' into 'a' that isn't actually a Float, you'll get a runtime exception.
Some people seem to think that arrays are worse than collections because of this, if I understand their posts correctly, but I probably don't because I don't see a problem with it. I wish collections could be as powerful as arrays! Then I could do away with using real arrays all together.
Oliver Wong - 29 Nov 2005 19:39 GMT > Of course, arrays are a different thing than collections; arrays are > more powerful and even a little dangerous. Float[] is a subtype of [quoted text clipped - 9 lines] > powerful as arrays! Then I could do away with using real arrays all > together. Under your definition of "more powerful", I think Collections are actually more powerful than arrays. If you want to say "I want a collection of Numbers, but I'm willing to take a collection of Floats, 'cause Floats are Numbers, and I'm just planning on pulling stuff out of the collection." then you would write, for example "ArrayList<? extends Number>". So with this syntax alone, Collections are of the same power as arrays. But you have more control over Collections.
You can also say "I want a collection. I don't care what kind of collection it is, but I wanna be able to put Numbers in it, so if you give me a collection of Objects, that's okay too." The syntax is "ArrayList<? super Number>".
Finally you can say "I want a collection of Numbers and nothing but numbers. Collection of Floats is no good, because I may want to insert Numbers, and collection of Objects is no good, because I want to be sure that when I take an element out, it's a Number". The syntax for that is "ArrayList<Number>".
- Oliver
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|