Nasty JDK varargs bug?

I may have just hit a nasty JDK varargs issue. If you have two constructors with the same number of non-vararg parameters and one of them has an additional varargs parameter, you need to be very careful which is called. Here is the code:

public void foo(Class klass, String str, String... names);

public void foo(Object obj, String str);

It looks like Java favors matching on parameter numbers and not types. If you invoke this method like this:

foo(Bean.class, "Bean");

It invokes the SECOND version and NOT the first! Looks like the JDK matches on the number of parameters (2) and ignores the fact that the first version of the method matches better because of typing and the fact that varargs is empty.

Thanks to a commenter, I found the section in the JLS that determines if variable argument methods are invoked:

“The first phase (§ performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.”

This states that in order to keep backwards compatibility, if first ignored methods with variable arguments (variable arity). This is ONLY for backwards compatibility and if JDK 5.0 was really a major release with no compatibility than my initial assessment of this being a bug would be true.

One thought on “Nasty JDK varargs bug?

  1. Is there a difference between arguments (String foo, String… bar) and (String… foobar)? I’m not sure and the guidelines say to be careful with it anyway:

    jdk 5 guide

    Generally speaking, you should not overload a varargs method, or it will be difficult for programmers to figure out which overloading gets called.

    Here’s the definitive statement on it, probably only requiring a couple of weeks of reading to figure out:

    JLS 3rd edition

    let’s hope this comes through without a preview


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s