Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
Win a copy of Soft Skills: The software developer's life manual this week in the Jobs Discussion forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Inconsistent vararg... behavior. Do you know why?

 
Harry Henriques
Ranch Hand
Posts: 206
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Below are two examples of vararg code. One compiles and the other doesn't. Can you explain why both of these examples don't compile?

Thxs,
Harry





C:\Documents and Settings\Harry Henriques\VARARGS>javac Vararg9.java
Vararg9.java:5: reference to vararg is ambiguous, both method vararg(long...) in
Vararg9 and method vararg(java.lang.Integer...) in Vararg9 match
vararg(new Integer(5), new Integer(5)); // doesn't compile
^
1 error





C:\Documents and Settings\Harry Henriques\VARARGS>vim Vararg11.java
 
Vivek Singh
Ranch Hand
Posts: 92
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harry Henriques wrote:



If a class declares a static method, then the declaration of that method is said to hide any and all methods with the same signature in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the class.

So thats why the overloaded method is not visible. Hence compilation fails.


 
Ankit Garg
Sheriff
Posts: 9495
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harry IMHO, Vararg9 should've compiled fine. You are not overloading int... and Integer... so the code should've compiled as per me. Maybe its a bug in the JVM.

Vivek there's nothing to do with superclass subclass here...
 
Vivek Singh
Ranch Hand
Posts: 92
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Method with varargs is called only when no other method signature matches the invocation.

in your case the signatures are same.
Good question though i also didnt know about this behaviour. ty
 
Andre Enimot
Ranch Hand
Posts: 31
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the reason for the "ambiguity" error that Henry gets is not because static methods are shadowed, but because the compiler can not decide which method to call. When one method is commented the ambiguity is resolved. Similar error would occur if one calls two overloaded methods that take say Integer... and int... with a Integer (or int) argument.
 
Vivek Singh
Ranch Hand
Posts: 92
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Andre Enimot wrote:I think the reason for the "ambiguity" error that Henry gets is not because static methods are shadowed, but because the compiler can not decide which method to call. When one method is commented the ambiguity is resolved. Similar error would occur if one calls two overloaded methods that take say Integer... and int... with a Integer (or int) argument.


no here its not the overloaded case....but varargs in java have some limitations.

Because the vararg variable must be the last parameter of the method.
Similarly Method with varargs is called only when no other method signature matches the invocation.
 
Horia Constantin
Greenhorn
Posts: 22
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Vivek
I don't understand you explanation...
compiles fine

@Andre: I agree with you, but why do we get this behaviour
@Vivek:
Method with varargs is called only when no other method signature matches the invocation.

in your case the signatures are same.
Good question though i also didnt know about this behaviour. ty
You're stating the obvious.. why aren't the signatures ok?

@Ankit: the code is not ok... compilation fails
 
Harry Henriques
Ranch Hand
Posts: 206
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ankit Garg wrote:
Harry IMHO, Vararg9 should've compiled fine. You are not overloading int... and Integer... so the code should've compiled as per me. Maybe its a bug in the JVM.


Ankit,

Vararg9 doesn't compile, but Vararg11 does compile. Do you really think that there is a bug in the JVM? I'm using Java 1.5

Thxs,
Harry
 
Kai Witte
Ranch Hand
Posts: 356
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

we had that here pretty often. I was the one who found it shortly after the release of 1.5.0_01, but it was not a bug. 1.5.0_01 and following RIs work according to the spec, while in the original 1.5.0 RI by Neal Gafter your code compiles.

http://www.coderanch.com/t/264427/Programmer-Certification-SCJP/certification/overloaded-var-args#1229316
Kai Witte wrote:
Neal Gafter started the implementation based on a preliminary (and as far as I know unpublished) vararg spec. According to that spec the check for the more specific method used similar rules to the ones in the check for method applicability, taking boxing into account. The author of the official JLS wrote it differently: Simpler, but less intuitive, without taking boxing into account. The result is that the official 1.5.0 RI does not work in full compliance with the JLS, which was "fixed" in 1.5.0_01.


Kai Witte wrote:
JLS 15.12.2.5, "Choosing the Most Specific Method" is relevant here. The subsection specifically for varargs is simple in our case, because in our case n = 1 and k = 1. Insert that and the description becomes quite simple. Basically it sais that the vararg part of a method is not relevant for choosing the most specific method. So neither method is more specific, and certainly not strictly more specific, than the other one.


Kai
 
Harry Henriques
Ranch Hand
Posts: 206
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kai Witte wrote:
JLS 15.12.2.5, "Choosing the Most Specific Method" is relevant here. The subsection specifically for varargs is simple in our case, because in our case n = 1 and k = 1. Insert that and the description becomes quite simple. Basically it sais that the vararg part of a method is not relevant for choosing the most specific method. So neither method is more specific, and certainly not strictly more specific, than the other one.


Hi Kai,

I can't understand why you say that one method isn't more specific than the other. In Vararg9, two literal long values are passed to static void vararg(long... x). The compiler knows that it cannot narrow these long literals to ints and then autobox them to Integers. Correctly, the compiler knows that the target for the two long literals is static void vararg(long... x).

In Vararg11, two Integer objects are instantiated as arguments to vararg(new Integer(5), new Integer(5)), but the compiler thinks that it can unbox the Integers and widen them as arguments to static void vararg(long... x). The compiler should know that it cannot do this. The compiler should know that it cannot "unbox and widen."

The two methods that I'm using for examples, i.e. Vararg9 and Vararg11, should both compile. I don't understand your reference to the JLS.

Thxs,
Harry Henriques
 
Ankit Garg
Sheriff
Posts: 9495
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Ankit: the code is not ok... compilation fails

I know the code fails to compile. But I think it should have compiled. The overloaded version has long... and Integer... and we are passing it Integer objects, so there should've been no ambiguity. The discussion here suggests that its a bug, and it seems a bug more because calling the method with two long parameters is compiling fine. I didn't look at the JLS to get a more clear understanding, I'll try to do that when I get time...
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic