“5.2.2 涉及基本类型的重载”举了两个例子,介绍了基本类型传递给重载方法中,如果重载方法定义了一些能够互相转化的类型时,会出现类型提升或者类型窄化的现象。下面先看一个基本类型从“较小”类型提升至“较大”类型的例子:
importstaticnet.mindview.util.Print.*; publicclassPrimitiveOverloading { voidf1(charx) { printnb("f1(char) "); } voidf1(bytex) { printnb("f1(byte) "); } voidf1(shortx) { printnb("f1(short) "); } voidf1(intx) { printnb("f1(int) "); } voidf1(longx) { printnb("f1(long) "); } voidf1(floatx) { printnb("f1(float) "); } voidf1(doublex) { printnb("f1(double) "); } voidf2(bytex) { printnb("f2(byte) "); } voidf2(shortx) { printnb("f2(short) "); } voidf2(intx) { printnb("f2(int) "); } voidf2(longx) { printnb("f2(long) "); } voidf2(floatx) { printnb("f2(float) "); } voidf2(doublex) { printnb("f2(double) "); } voidf3(shortx) { printnb("f3(short) "); } voidf3(intx) { printnb("f3(int) "); } voidf3(longx) { printnb("f3(long) "); } voidf3(floatx) { printnb("f3(float) "); } voidf3(doublex) { printnb("f3(double) "); } voidf4(intx) { printnb("f4(int) "); } voidf4(longx) { printnb("f4(long) "); } voidf4(floatx) { printnb("f4(float) "); } voidf4(doublex) { printnb("f4(double) "); } voidf5(longx) { printnb("f5(long) "); } voidf5(floatx) { printnb("f5(float) "); } voidf5(doublex) { printnb("f5(double) "); } voidf6(floatx) { printnb("f6(float) "); } voidf6(doublex) { printnb("f6(double) "); } voidf7(doublex) { printnb("f7(double) "); } voidtestConstVal() { printnb("5: "); f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5); print(); } voidtestChar() { charx=‘x’; printnb("char: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } voidtestByte() { bytex=0; printnb("byte: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } voidtestShort() { shortx=0; printnb("short: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } voidtestInt() { intx=0; printnb("int: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } voidtestLong() { longx=0; printnb("long: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } voidtestFloat() { floatx=0; printnb("float: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } voidtestDouble() { doublex=0; printnb("double: "); f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x); print(); } publicstaticvoidmain(String[] args) { PrimitiveOverloadingp=newPrimitiveOverloading(); p.testConstVal(); p.testChar(); p.testByte(); p.testShort(); p.testInt(); p.testLong(); p.testFloat(); p.testDouble(); } }
/* Output:
5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double)
char: f1(char) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double)
byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) f6(float) f7(double)
short: f1(short) f2(short) f3(short) f4(int) f5(long) f6(float)
f7(double)
int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double)
long: f1(long) f2(long) f3(long) f4(long) f5(long) f6(float) f7(double)
float: f1(float) f2(float) f3(float) f4(float) f5(float) f6(float)
f7(double)
double: f1(double) f2(double) f3(double) f4(double) f5(double)
f6(double) f7(double)
*///:~
上述例子中,int类型会被提升为float,long,double分别调用提升类型的重载函数。同理,如果传一个“较大”类型的参数比如double,会被窄化成long,float,int等分别调用窄化类型的重载函数。在这里就不贴窄化例子的代码了,读者可以自己模仿实验一下。要重点说明的是,一般很少定义这么多重载函数,可能一些库和框架会用到,但是他们一般会做一些类型判断,可能只以Object作为参数类型。
“5.2.3 以返回值区分重载方法”,从这一小节的命名可以看出来是一个行不通的方案。虽然我们可以从有返回值的方法中获取返回值,但是在调用方法的时候,可以不获取返回值,这就让编译器无法区分调用那个方法,所以,不能以返回值区分重载方法方法。举例说明:
void f() {}
int f() { return 1; }
如果像下面这样调用方法:f();此时Java如何才能判断调用哪一个f()呢?答案是无法判断。