Overloading with Widening、Boxing and Var

阅读: 评论:0

Overloading with Widening、Boxing and Var

Overloading with Widening、Boxing and Var


区别不同函数的唯一标志是参数列表,重载的函数,它们的函数名相同,返回类型可以相同也可以不同,但它们的参数列表一定不能相同。与继承中的方法重写不同,重写的方法要求函数名和参数列表一定相同。


There are three factors that make overloading a little tricky:

(1) Widening

(2) Boxing

(3) Var-args


1. 自动提升时的规则

class EasyOver {static void go(short x) { System.out.print("short "); }static void go(int x) { System.out.print("int "); }static void go(long x) { System.out.print("long "); }static void go(double x) { System.out.print("double "); }public static void main(String [] args) {char c = 'a';byte b = 5;                                                                            short s = 5;long l = 5;float f = 5.0f;go(c);         //go(int)go(b);         //go(short)go(s);         //go(short)go(l);         //go(long)go(f);         //go(double)}
}

Which produces the output:



This probably isn't much of a surprise. 

In every case, when an exact match isn't found, the JVM uses the method with the smallest argument that is wider than the parameter.

char produces a slightly different effect, since if it do not find an exactchar match,it is promoted to int. char can not be promotedbyte and short whenever it is, it can be promotedlong,float and double if int does not exist.


2. Overloading with Boxing and Var-args

(1) overloading with boxing

class AddBoxing {static void go(Integer x) { System.out.println("Integer"); }static void go(long x) { System.out.println("long"); }public static void main(String [] args) {int i = 5;go(i); // which go() will be invoked?}
} 

Does the compiler think that widening a primitive parameter is more desirable than performing an autoboxing operation? The answer is that the compiler willchoose widening over boxing, so the output will be:
     


(2) overloading with var-args

class AddVarargs {static void go(long x, long y) { System.out.println("long,long");}static void  x) { System.out.println(&# "); }       public static void main(String[] args) {byte b = 5;go(b,b);      // which go() will be invoked?}
}

The output is:



So far, we have seen that

(*) Wideningbeats boxing

(**) Widening beats var-args


At this point, inquiring minds want to know, does boxing beat var-args?

(3) Box or Var-args

class BoxOrVararg {static void go(Byte x, Byte y) { System.out.println("Byte, Byte"); }static void  x) { System.out.println(&# "); }                                          public static void main(String [] args) {byte b = 5;go(b,b);         // which go() will be invoked?}
}

As it turns out, the output is



So we have seen another rule:

(*) boxing beats var-args

And var-args is the last choice to select.


3. Overloading When Combining Widening and Boxing

In this case the compiler will have to widen and then autobox the parameter for a match to be made:

class WidenAndBox {static void go(Long x) { System.out.println("Long"); }public static void main(String [] args) {byte b = 5;go(b);      //widen then box, it is illegal                                            }
}

This is just too much for the compiler:



Widen then box, it is illegal.

Strangely enough, it IS possible for the compiler to perform a boxing operation followed by a widening operation in order to match an invocation to a method.

class BoxAndWiden {static void go(Object o) {Byte b2 = (Byte) o;     // ok - it's a Byte objectSystem.out.println(b2);}public static void main(String [] args) {byte b = 5;go(b);                 // can this byte turn into an Object ?                          }
}

This compiles (!), and produces the output:



It should box then widen.

Wow! Here's what happened under the covers when the compiler, then the JVM, got to the line that invokes the go() method:
1) The byte b was boxed to a Byte.
2) The Byte reference was widened to an Object (since Byte extends Object).
3) The go() method got an Object reference that actually refers to a Byte object.
4) The go() method cast the Object reference back to a Byte reference (remember, there was never an object of type Object in this scenario, only anobject of type Byte!).
5) The go() method printed the Byte's value.


4. Overloading in Combination with Var-args

What happens when we attempt to combine var-args with either widening or boxing in a method-matching scenario? Let's take a look:

class Vararg {static void wide_ x) { System.out.println(&#"); }static void box_ x) { System.out.println(&#"); }public static void main(String [] args) {int i = 5;wide_vararg(i,i);      // needs to widen and use var-argsbox_vararg(i,i);       // needs to box and use var-args}
}

This compiles and produces:



As we can see, you can successfully combine var-args with either widening or boxing. 

So the following codes wil be failed.

class Ambiguous {static void  x) { System.out.println(&#"); }static void  x) { System.out.println(&#"); }public static void main(String [] args) {int i = 5;vararg(i,i);      // widen first or box first and before using var-arg? Both yes!}                                                                                          
}

This is just too much for the compiler:



Another example:

public class Ambiguous2 {public static void test(float a,  c) {System.out.println("float, ");}public static void  c) {System.out.println(&#");}public static void main(String[] args) {test('a', 'b'); // widen first or box first before using var-arg ?}
}

This is also too much for the compiler:



5. review of the rules for overloading methods using widening, boxing, and var-args


(1) Primitive widening uses the "smallest" method argument possible.

(2) Used individually, boxing and var-args are compatible with overloading.

(3) You CANNOT widen from one wrapper type to another. (IS-A fails.)

(4) You can box and then widen. (An int can become an Object, via Integer.)

(4) You can combine var-args with either widening or boxing.



本文发布于:2024-01-28 23:33:34,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170645602111098.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Widening   Overloading   Var   Boxing
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23