Overloading with Widening、Boxing and Var-args
来源:互联网 发布:angular js 跨域访问 编辑:程序博客网 时间:2024/05/21 21:41
区别不同函数的唯一标志是参数列表,重载的函数,它们的函数名相同,返回类型可以相同也可以不同,但它们的参数列表一定不能相同。与继承中的方法重写不同,重写的方法要求函数名和参数列表一定相同。
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 toint. char can not be promotedbyte andshort whenever it is, it can be promotedlong,float anddouble 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 go(byte... x) { System.out.println("byte... "); } 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 go(byte... x) { System.out.println("byte... "); } 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 object System.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_vararg(long... x) { System.out.println("long..."); } static void box_vararg(Integer... x) { System.out.println("Integer..."); } public static void main(String [] args) { int i = 5; wide_vararg(i,i); // needs to widen and use var-args box_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 vararg(long... x) { System.out.println("long..."); } static void vararg(Integer... x) { System.out.println("Integer..."); } 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, Character... c) { System.out.println("float, Character..."); } public static void test(Character... c) { System.out.println("Character..."); } 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.
- Overloading with Widening、Boxing and Var-args
- Playing Around with Methods Overloading, C-language and Operators (1)
- 11.3 Boxing and unboxing
- Boxing and Unboxing
- Boxing and Unboxing
- Boxing and Unboxing
- 10.6 Signatures and overloading
- OverLoading and Scope
- Overloading And Overriding
- BOXING AND UNBOXING FOR BEGINNER
- Boxing and unboxing in C#
- Programming in Emacs Lisp笔记(六) Narrowing and Widening
- Overloading '+' VS. StringBuilder and StringBuffer
- Method of Overriding and Overloading
- Function overloading and const keyword
- Name Mangling and Function Overloading
- C++ Overloading (Operator and Function)
- python *args and * kwargs
- 代码审查“思维导图”
- JQuery Mobile移动Web应用开发(2):开发环境搭建
- java的同步机制
- 5.Spring bean常见属性的注入:测试
- php 函数重载
- Overloading with Widening、Boxing and Var-args
- 设计模式——中介者
- 全国各地骗子大比武
- 需要看的 android 资料
- eclipse android 绑定 第三方 源代码
- 如果系统能够保证不在0x000000007fffffff以上的地址分配内存,那么应用程序就能够正常运行。把一个高33位都为0的64位地址截断为32位地址,无论如何都不会产生问题。系统可以提供这一保证,
- Pku2352 Stars 树状数组
- 我佛慈悲 赐我雨水
- poj_1523 SPF (求割点)