• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Overloading with varargs and array parameters, strange inconsistency?

 
Andreas Svenkson
Ranch Hand
Posts: 179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys.

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?

// Andreas
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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[].

 
Stephan van Hulst
Bartender
Pie
Posts: 6128
74
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.

[edit]

9 freakin' seconds :P
 
Andreas Svenkson
Ranch Hand
Posts: 179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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).

// Andreas
 
Andreas Svenkson
Ranch Hand
Posts: 179
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hehe, 2 responses during the time it took me to phrase my 2nd post =)

Thanks guys. Although I must say, I still find it a tiny bit inconsistent with the whole "varargs are catchall" phrasing from the book.

// Andreas
 
Rahul Sudip Bose
Ranch Hand
Posts: 637
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I got a warning after compilation(you should have mentioned this !). Here is the warning and the output for anyone who is trying to help us :

WARNING :



OUTPUT :


PS : Its back to the basics for me now
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 .
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic