PROPOSAL: Simplified Varargs Method Invocation

Rémi Forax forax at univ-mlv.fr
Fri Mar 6 00:28:38 PST 2009


Reinier Zwitserloot a écrit :
> Heh, that was the next proposal I was going to write.
>
> (Apologies for a long and technically complicated post. I've rewritten  
> it several times in an attempt to get to the point faster, but this is  
> the best I can do).
>
> It really pains me to rain on your parade. I was doing some  
> experimenting and found an admittedly very unlikely scenario that  
> isn't backwards compatible. Then I realized, that this is actually  
> (arguably) a bug, or at least a severe misfeature in javac right now!  
> Therefore, this proposal should fix this problem as well. Of all  
> proposals so far, I rate this one the highest, because it causes so  
> much confusion and is closer to a bug in javac than a language  
> feature, so I would be very happy if this proposal can be fully ironed  
> out.
>
> Complete code showing the problem - copy and paste into Main.java,  
> compile, and run:
>
> ------
>
> import java.util.*;
>
> class Foo<T> {
> 	public void foo(T... t) {}
> }
>
> class Bar extends Foo<String> {
>          //de-varargsing? Why is this legal?
>   
Because you want to be able to replace an array with a varargs in 
library without
creating errors in code that use that library.
> 	public void foo(String[] t) {
> 		System.out.println(t.getClass().getComponentType());
> 	}
> }
>
> public class Main {
> 	public static void main(String[] args) {
> 		Foo<String> f = new Bar();
> 		List<String> l = Arrays.asList("a", "b", "c");
> 		bar(f, l);
> 	}
> 	
> 	public static <T> void bar(Foo<T> f, List<T> l) {
> 		f.foo(l.get(0), l.get(1), l.get(2));
> 	}
> }
>   

> -----
>
> The result is an error:
>
> Exception in thread "main" java.lang.ClassCastException:  
> [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
>
> Right now, you get the usual varargs warning, but nothing else at  
> compile time. At runtime, you get the above error.
>   
Warnings in Java are not like in C, it means something will go wrong :)

the call:

f.foo(l.get(0), l.get(1), l.get(2));

generate a warning because you are creating an arry of parameterized type
(a Foo<T>[]) which are "inherently unsafe" to quote gilad bracha.

> The real bug here is the ability for any subclass to de-varargs a  
> parameter.
No

[...]

See:
>> Angelika Langer's Java Generics FAQ, "Why does the compiler  
>> sometimes issue
>> an unchecked warning when I invoke a 'varargs' method?" (
>> http://tinyurl.com/8w2dk)
>>     
Rémi



More information about the coin-dev mailing list