I was just rehearsing the rules of overloading with vararg parameters, boxing etc, and found something strange when I looked into mixing arrays and varargs.
Consider the following code:
Basically, the first invocation of go() will invoke the "Object instance" method, which is fine and in all ways correct. However, the second invocation using an array of class C as argument actually invokes the "Object vararg" method, something I find strange, and inconsistent. Imo it also goes against the premise that vararg methods are to be considered "catch all methods", which I am sure I have read in K&B but can't point to the page this very moment.
Does anyone else find it strange that the (Object... oa) method is chosen before the (Object o) for the argument array C[] ? Can you explain it?
I think the reason is that a var-args method gets converted to one that takes an object array. In other words:is equivalent to You can confirm this by adding both methods - it won't compile because they conflict.
As such, although it's slightly confusing, the var-args method is getting called because it's a better match - a C[] is closer to an Object[] than it is to Object. Whereas the first doesn't match because a byte[] is-not-an Object[].
When calling an overloaded method, the method with the most specific parameter type will be invoked, as long as the argument fits.
The first call will invoke go(Object) because byte[] isn't a subtype of Object[].
The second call will invoke go(Object[]) because C[] is a subtype of Object[], and go(Object[]) is more specific than go(Object); since Object[] is a subtype of Object.
Thinking about it, I suspect an explanation might have to do with the inheritance tree for an instance array.
Assuming the following inheritance tree is correct:
C[] <- Object[] <- Object
Where "<-" = extends.
Then one could perhaps argue that the C[] is sooner converted to an Object[], than it is to an Object instance. And furthermore the Object[] is considered a match to the method parameter (Object... oa) before it matches the parameter (Object o).
If you want to get into the messy details, the Java Language Specification explains how it all works. Having had a quick look, that's not the most accessible part of the specs I've read, so good luck .
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.