Java SE 是什么,包括哪些内容(九)?
本文内容参考自Java8标准
Java中的基本类型有一个特性:它能自动从一个"较小"的类型转换成"较大"的类型!
上面这句话什么意思呢?指的就是byte、char、short等"较小"类型能自动转换成int类型,而不需要额外的其他操作。
因此,如果这个自动转换的过程涉及到重载,可能会造成混淆。
下面举例说明将基本类型传递给重载方法时的情况:
1、传入的参数类型小于等于重载方法的形式参数类型。
// 将基本类型传递给重载方法
public class PrimitiveOverloading{
//根据输出的字符串来确认调用的是哪一个方法。
//方法f1()-f7()逐步减少重载的方法是采取了排除法。
void f1(char x){System.out.print("f1(char)");}
void f1(byte x){System.out.print("f1(byte)");}
void f1(short x){System.out.print("f1(short)");}
void f1(int x){System.out.print("f1(int)");}
void f1(long x){System.out.print("f1(long)");}
void f1(float x){System.out.print("f1(float)");}
void f1(double x){System.out.print("f1(double)");}
void f2(byte x){System.out.print("f2(byte)");}
void f2(short x){System.out.print("f2(short)");}
void f2(int x){System.out.print("f2(int)");}
void f2(long x){System.out.print("f2(long)");}
void f2(float x){System.out.print("f2(float)");}
void f2(double x){System.out.print("f2(double)");}
void f3(short x){System.out.print("f3(short)");}
void f3(int x){System.out.print("f3(int)");}
void f3(long x){System.out.print("f3(long)");}
void f3(float x){System.out.print("f3(float)");}
void f3(double x){System.out.print("f3(double)");}
void f4(int x){System.out.print("f4(int)");}
void f4(long x){System.out.print("f4(long)");}
void f4(float x){System.out.print("f4(float)");}
void f4(double x){System.out.print("f4(double)");}
void f5(long x){System.out.print("f5(long)");}
void f5(float x){System.out.print("f5(float)");}
void f5(double x){System.out.print("f5(double)");}
void f6(float x){System.out.print("f6(float)");}
void f6(double x){System.out.print("f6(double)");}
void f7(double x){System.out.print("f7(double)");}
//方法testConstVal()
void testConstVal(){
//打印字符串"5:".
System.out.print("5:");
//参数是5,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
//或者换句话说,将5当做了什么类型处理。
f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testChar()
void testChar(){
char x = 'x';
//打印字符串"char:".
System.out.print("char:");
//参数是char类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testByte()
void testByte(){
byte x = 0;
//打印字符串"byte:".
System.out.print("byte:");
//参数是byte类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testShort()
void testShort(){
short x = 0;
//打印字符串"short:".
System.out.print("short:");
//参数是short类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testInt()
void testInt(){
int x = 0;
//打印字符串"int:".
System.out.print("int:");
//参数是int类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testLong()
void testLong(){
long x = 0;
//打印字符串"long:".
System.out.print("long:");
//参数是long类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testFloat()
void testFloat(){
float x = 0;
//打印字符串"float:".
System.out.print("float:");
//参数是float类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//方法testDouble()
void testDouble(){
double x = 0;
//打印字符串"double:".
System.out.print("double:");
//参数是double类型,分别调用f1()-f7().
//通过具体的结果字符串了解调用的是哪一个参数类型的方法。
f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
//不输出任何内容,作用就是换行。
System.out.println();
}
//程序执行的入口main方法。
public static void main(String[] args){
//创建对象。
PrimitiveOverloading p = new PrimitiveOverloading();
//方法调用。
p.testConstVal();
p.testChar();
p.testByte();
p.testShort();
p.testInt();
p.testLong();
p.testFloat();
p.testDouble();
}
}
以上示例代码的执行结果解析如下:
第一个方法testConstVal(),因为方法f1()-f4()中都有int类型参数的重载方法,所以f1()-f4(),5都被作为int类型来处理了(结果都是int类型的结果:f1(int)f2(int)f3(int)f4(int)),而f5()-f7(),没有int类型的重载方法,所以5只能被当做其中范围最小的类型来处理(f5()是long类型,f6()是float类型,f7()是double类型:从结果可以看出:f5(long)f6(float)f7(double))。
第二个方法testChar(),已经明确了参数x就是char类型,仅有f1()有类型为char的重载方法,所以直接作为char类型处理了(f1(char)),但是f2()-f4()没有char类型的重载方法,所以char类型被直接升级为int类型处理(结果都是int类型的结果:f2(int)f3(int)f4(int)),而f5()-f7(),都是将char类型直接升级为最小范围的重载类型处理(f5()是long类型,f6()是float类型,f7()是double类型:从结果可以看出:f5(long)f6(float)f7(double))。
第三个方法testByte(),已经明确了参数x就是byte类型,f1()-f2()中都有byte类型的重载方法,所以都被当成byte类型处理(f1(byte)f2(byte)),f3()-f7()中都没有byte类型的重载方法,所以都被当成了f3()-f7()中范围最小的数据类型处理(f3()是short,f4()是int,f5是long,f6()是float,f7()是double)。
第四个方法testShort(),已经明确了参数x就是short类型,结果性质与第三个方法是一致的,有重载类型就按重载类型处理,没有就按数据范围最小的那个处理。
第五个方法testInt(),已经明确了参数x就是int类型,结果性质与第一个方法是一致的,第一个方法直接输入5,因为没有明确这个5是什么类型的,所以使用的是Java的默认类型,就是int,所以testConstVal()就相当于testInt()。
第六个方法testLong(),已经明确了参数x就是long类型,f1()-f5()都有long类型的重载方法,所以都被当成long类型处理,f6()-f7()中都没有long类型的重载方法,所以都被当成了f6()-f7()中范围最小的类型处理(f6()是float,f7()是double)。
第七个方法testFloat(),与第六个方法结果性质一致。
第八个方法testDouble(),f1()-f7()都有double类型的重载方法,所以全都当成double类型处理了。
总结起来就是:常数值5被当成了int类型处理,因为Java中默认使用的数值就是int类型的,所以如果有某个方法接受int类型的参数,它就会被调用,如果传入的数据类型小于方法中的形式参数类型,比如f6()中最小的类型都是float类型,这时你传入一个int类型的数值,那么它就会被自动升级为float类型。然后得出结果。char类型有一些特殊,如果无法直接找到char类型的重载方法,那么char类型就会直接升级为int类型。
2、传入的参数类型大于重载方法的形式参数类型。
// 传入的实际参数类型大于重载方法的形式参数类型
public class Demotion{
//根据输出的字符串来确认调用的是哪一个方法。
//方法f1()-f7()逐步减少重载的方法是采取了排除法。
void f1(char x){System.out.print("f1(char)");}
void f1(byte x){System.out.print("f1(byte)");}
void f1(short x){System.out.print("f1(short)");}
void f1(int x){System.out.print("f1(int)");}
void f1(long x){System.out.print("f1(long)");}
void f1(float x){System.out.print("f1(float)");}
void f1(double x){System.out.print("f1(double)");}
void f2(char x){System.out.print("f2(char)");}
void f2(byte x){System.out.print("f2(byte)");}
void f2(short x){System.out.print("f2(short)");}
void f2(int x){System.out.print("f2(int)");}
void f2(long x){System.out.print("f2(long)");}
void f2(float x){System.out.print("f2(float)");}
void f3(char x){System.out.print("f3(char)");}
void f3(byte x){System.out.print("f3(byte)");}
void f3(short x){System.out.print("f3(short)");}
void f3(int x){System.out.print("f3(int)");}
void f3(long x){System.out.print("f3(long)");}
void f4(char x){System.out.print("f4(char)");}
void f4(byte x){System.out.print("f4(byte)");}
void f4(short x){System.out.print("f4(short)");}
void f4(int x){System.out.print("f4(int)");}
void f5(char x){System.out.print("f5(char)");}
void f5(byte x){System.out.print("f5(byte)");}
void f5(short x){System.out.print("f5(short)");}
void f6(char x){System.out.print("f6(char)");}
void f6(byte x){System.out.print("f6(byte)");}
void f7(char x){System.out.print("f7(char)");}
//方法testDouble直接使用了范围最大的类型double进行测试。
void testDouble(){
//创建测试的变量,类型为double,名称为x.
double x = 0;
//打印字符串:"double augument:"
System.out.print("double augument:");
//传入double类型的实际参数.
f1(x);
//以下的方法都做了强制转换,因为它们的数据范围都要比double类型的要小。
//将x做强制转换,转换为float类型。所以传入的参数实际为float类型。
f2((float)x);
//将x做强制转换,转换为float类型。所以传入的参数实际为float类型。
f3((long)x);
//将x做强制转换,转换为float类型。所以传入的参数实际为float类型。
f4((int)x);
//将x做强制转换,转换为float类型。所以传入的参数实际为float类型。
f5((short)x);
//将x做强制转换,转换为float类型。所以传入的参数实际为float类型。
f6((byte)x);
//将x做强制转换,转换为float类型。所以传入的参数实际为float类型。
f7((char)x);
}
//程序执行的入口main方法。
public static void main(String[] args){
//创建对象。
Demotion d = new Demotion();
//调用方法。
d.testDouble();
}
}
结果示例:
从结果可以看出,如果方法只接受较小范围的参数,而传入的参数范围更大,需要通过强制转换,否则编译器会报错!程序无法执行。
如图:
PS:时间有限,有关Java SE的内容会持续更新!今天就先写这么多,如果有疑问或者有兴趣,可以加QQ:2649160693,并注明CSDN,我会就博文中有疑义的问题做出解答。同时希望博文中不正确的地方各位加以指正!