• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Widening,Boxing and Var-Args Combined

 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider the following code:




When i run the program, i get compilation error saying - reference to wide_range is ambiguous.

So, we can't combine var-arg with boxing and widening simultaneously,is it?

Kathy Sera P.No- 253 also says:
"Combining var-args with EITHER widening or boxing in a method-matching scenario


So, does EITHER here suggest the same thing?

Shouldn't it happend that since var-args is used in both static functions, widening should be given preference over Boxing and the output of the program should be:

long...

rather than a compilation error........


Waiting for enlightenment.....
 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your call is ambiguous. Methods themselves are perfectly fine. While widening is chosen over boxing, with var-args things get a bit more complicated.

These calls also throw compile time error.


Since var-args mean 0 or more parameters, and an array again fits both methods. Whitch is realy weird, since there is no


I wonder if I made it more clear or more confusing.

 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If at all only one method(out of the two in the code) is used at a time,

then the call runs fine.

I have no problem with understanding call to var-args so any explanation related to that is not what i expect.....

I have problem with "why the ambiguity coming", aren't those two perfect declaration of 2 overloading methods?

 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Martin Vanyavchich wrote:Your call is ambiguous. Methods themselves are perfectly fine.
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, var-args can be used EITHER with boxing or with widening, but not with both simultaneously.....

is that what i should conclude?
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Common yaar, give me an answer!!

 
Vinayagar Karpagam
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prateek,

If one cannot be used, there is no use in the compiler and run-time allowing it. If they both allow it, there must be a way to use it. Isn't it?
And we can use var-args with boxing and widening and both simultaneously, just that we got to be more specific in the caller so as to avoid ambiguity.

It would be great for yourself if you can find an appropriate way to call the methods. That way, you can conclude by yourself how it works.
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not able to get your explanation.....

I have concluded that 2 legal overloaded methods involving var-args can produce ambiguity. Consider 3 cases:

1)
static void wide_range(long... x)

and

static void wide_range(Integer... x)

produces ambiguity when int is passed,because int can be widened to long as well as boxed into Integer.

2)
static void wide_range(long... x)

and

static void wide_range(int... x)

produces ambiguity when int is passed,because int is and int and it can be widened to long.

3)
static void wide_range(int... x)

and

static void wide_range(Long... x)

DOESN'T produces ambiguity when int is passed,because int can't be promoted to Long(widening and boxing not allowed).
 
Vinayagar Karpagam
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prateek,

The compiler won't widen and box simultaneously whether there is var-args or not. I believe the issue we were discussing here is not simultaneous widening and boxing. It is about having 2 var-args, one with boxing and the other with widening. And it is supported. But we need to be more specific in the caller to avoid the ambiguity.
 
Sahil Kapoor
Ranch Hand
Posts: 316
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whenever you have a conflict within var-args

remember , Exact Match, Widening and Boxing all have the same priority and thus ambiguous. This is my deduction from various experiments , also this is not true for Objects, it is true only for primitives.

Cheers!!!
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know that compiler won't widen and box even when var-arg is not involved.

Yes, i know the ambiguity can be avoided, for instance in case 2,ambiguity is avoided by making a call as shown below:

int i = 4;
wide_range((long)i,(long)i);

But the problem is this "ambiguity-resolution" that has to be done manually by us and not by compiler,,,,,
 
Shanky Sohar
Ranch Hand
Posts: 1051
Eclipse IDE Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Consider the following code:



Note few things :-

Cimpiler choose
1.widening then
2.autoboxing and then
3.variable argument methods.

intially in your code there is no widening...widening is done only after autoboxing from int to long
What your code is trying to do with this method is.....


it tries to autobox the int to long........


in both the above two cases autoboxing is done from
1.) from int to long
2.) from int to Integer

So compiler is getting confused which method to chosse from both.................


If you comment either of two methods then your code will compile fine.......




or




 
Shanky Sohar
Ranch Hand
Posts: 1051
Eclipse IDE Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
similarlyy see this code also .........




The problem now is obvious: since String implements both Comparable and
Serializable, the compiler cannot know which method you intend to call.

A simple cast will solve the problem:

ambiguousMethod((Comparable)"bar");
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your illustration of String,Comparable and Serializable is good.


But notice what you said:



in both the above two cases autoboxing is done from
1.) from int to long
2.) from int to Integer



and


intially in your code there is no widening...widening is done only after autoboxing from int to long
What your code is trying to do with this method is.....

static void wide_range(long... x){
System.out.println("long...");
}


it tries to autobox the int to long........




Well, int to long is not autoboxing as far as i know, its widening.....

How can both involves auto-boxing then?

and when only the following method is there in the class:



then it works not because it involves autoboxing but because it involves widening......

What say?
 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prateek Rawal wrote:


Waiting for enlightenment.....


Next time Prateek ... check your copy/pasty from K&B



You are mixing (widenig and boxing) with varagrs and (widenig and boxing and varargs) with overloaded methods.
To answer your question
Prateek Rawal wrote:So, we can't combine var-arg with boxing and widening simultaneously,is it?

Yes, yes we can. Overloading? Whole other story!
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey Martin,

Do you think i'm that much an idiot to have done error copying something from K & B, and do you think these gentlemen who have been replying and posting to my threads are all fool to respond to a wrong question.....

Man, my question is ofcourse inspired from the example which you quoted, but that doesn't mean i was refering to that question and made an error copying it....

On going through that example, i pondered what would happen if both the methods would have the same name, and then i ran my query into my laptop and it gave error saying ambiguity......and that's when i posted it on "javaranch"....

A serious advice to you: Before replying to a thread, make sure you read earlier messages.......
 
Henry Wong
author
Marshal
Pie
Posts: 21489
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prateek Rawal wrote:Hey Martin,

A serious advice to you: Before replying to a thread, make sure you read earlier messages.......


Prateek,

Admittedly, Martin's response could have been worded better -- but I am sure that he didn't intend to offend you. Basically, the JLS is pretty vague when it comes to mixing var-args with overloading, and in fact, Sun documents even mention that you should try not mixing the two.

Henry
 
Shanky Sohar
Ranch Hand
Posts: 1051
Eclipse IDE Firefox Browser
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry in hurry i write that......
int to long is a autoboxing................

the conclusion is that............conpiler is really confused.....which method to invoke between the two......



the maine part plays in your code is by this line


when we do this...what it will do..........it will pass the copy of i to wide_range(remember only the copy not the actual value)

and as you know widening happens automatically...............
by the time copy if i varaible reaches the above two methods......
both of the methods are avilable to accomodate it...............as long can also take int values.............

if you change your code to


then compiler is very happy about that.............as short cannot take int values.......but if you want to invoke short method then do



it will invoke

thanks for asking challenging question i really wanna see tough question.that require too much exploring................
 
Prateek Rawal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically, the JLS is pretty vague when it comes to mixing var-args with overloading, and in fact, Sun documents even mention that you should try not mixing the two.


Thanks Henry for finally giving me some solid CONCLUSION

@phil:

Thanks, man!

Btw, what you summed up :


but if you want to invoke short method then do

class Humm {


static void wide_range(Short... x){
System.out.println("short...");
}

static void wide_range(Integer... x){
System.out.println("Integer...");
}

public static void main(String[] args) {

int i = 5;
wide_range((short)i,(short)i);

}
}



Well, if you read the previous posts of mine to this thread, you will find that i made 3 cases, and the one you gave was one of them....

Anyways, thanks for your response.
Cheers all!!!
 
ankur trapasiya
Ranch Hand
Posts: 160
Java Netbeans IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hey prateek..!! This is the conclusion that i found by trying so many examples and searching over the internet.

When there is a choice between int and Integer(similarly compatible data types other than var args (see (1)) at that time compiler can make wise decisions based on the data that is passed to the method, but when there are more than one var args method then compiler cannot compare them because they both are arrays (e.g. long... represents array of long and Integer... represents array of Integers (see (2))). So here compiler will look to see if there is more than one method which can fulfill the requirements(in the sense of parameters) of method then it will found that there is ambiguity because of non comparability between var args and if it finds the perfect match then it will execute it.


(1)
static void go(int i)
{
System.out.println("(int i)");
}
static void go(Integer i)
{
System.out.println("(Integer i)");
}

(2)

static void go(int... i)
{
System.out.println("(int... i)");
}
static void go(long... l)
{
System.out.println("(long... i)");
}
public static void main(String[] args)
{
go(l1,l2,l3); // compiler cannot compare long array and int array so it checks to see if there is method that can fulfill requirements of this method call but it finds two such methods so it gives compiler error.
}


if you still confused then refer this

webpage

 
Imad Aydarooos
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ankur trapasiya wrote:hey prateek..!! This is the conclusion that i found by trying so many examples and searching over the internet.

if you still confused then refer this

webpage


The article is great...thanks
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic