PROPOSAL: Simplified Varargs Method Invocation

Bob Lee crazybob at crazybob.org
Fri Mar 6 00:02:25 PST 2009


On Thu, Mar 5, 2009 at 9:39 PM, Reinier Zwitserloot <reinier at zwitserloot.com
> wrote:

> (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).
>

Not at all. This is great. Thanks for the feedback, Reinier!

Right now, you get the usual varargs warning, but nothing else at
> compile time. At runtime, you get the above error.
>

I get this warning on Bar.foo(String[]): "cannot override foo(T...) in Foo;
overriding method is missing '...'" I get a similar warning when I try to
override an array method with a varargs method.


> The more serious problem, and one directly related to the proposal, is
> trying to reify a superclass's array type. (the subclass in the
> example above turning Foo's T into a reified 'String'). This action is
> fundamentally broken, and yet there's no way to avoid it. You can't
> effectively override a method of a superclass containing a generics
> type as an array's component type if you reified that generics
> parameter. You can try, but many callers simply can't call your method
> anymore. Right now, in java 1.5/1.6, you do get that generics warning
> Bob Lee's proposal is trying to move to the callee site, though it's
> not very informative and there's absolutely nothing a caller can do
> whatsoever. If Bob Lee's proposal is implemented, the warning just as
> useless, and arguably skipped even faster than it is now.
>
>  Specifically, you can't:
>
> A: widen the type of the parameter in the overriding method's
> signature to Object[] or Object..., as javac will refuse to compile it
> due to two different signatures erasing to the same signature.
>
> B: add a bogus <T extends String> type and use that T. Javac will
> compile it, but the signature of that method is then foo(String[]),
> and thus its a completely separate method, that doesn't override
> parent's foo method.
>

Good catch. I hadn't thought about this. It would be nice if javac could
just erase to Object[] in the overridding method, but I can't say whether or
not that's a viable option. Looks like I have some investigation ahead of
me.

A second addendum I would strongly urge is to use escape detection to
> eliminate the warning on the var-args-using methods. The following
> operations are all entirely safe, and they are also the only ones used
> by every single varargs method I've ever laid my eyes on, except
> Arrays.asList:
>

This is what I meant by alternative e) defile the type system. :-)

Basically, you can always just store the varargs value in an Object
variable. When I discussed this with Alex Buckley, he found generating a
warning in this case too distastful.

On the bright side, this warning only turns up 3 times in the entire JDK, so
it's probably best to keep the proposal simple.

Note that for most of these cases, there are mixed-version problems.
> New code that calls into old code means nobody gets any warnings. I'm
> not sure if Bob's proposal includes this, but the compiler should
> continue to generate warnings on the site of the caller if the class
> file format of the targeted method goes with javac v1.6 or below.
>

The proposal covers this in the spec: "if the target method was compiled
targeting Java 7 or later"

Bob



More information about the coin-dev mailing list