Java类型自动转换

今天突然想起Java的数值类型自动转换,于是做了个测试,设计思路有点沙雕

先看看Java类型自动转换的图

(实线代表无损转换,虚线代表可能有精度损失的转换)

 

先定义两个变量,byte q; 和 long w;

然后用这两个变量调用包含不同类型参数的方法,看看会发生什么

参照 byte --->  short  --->  int  --->  long  --->  float  --->  double  ;

(byte --->  short 为 1,byte  --->  int 为2;以此类推)

 

一、一个方法是参数x的类型差两位,参数y的类型差一位。另一个方法是参数x的类型差一位,参数y的类型差两位。

public class Test {
//    x参数类型相差两位,y参数类型相差一位
    static void typeConversion(int x,float y){
        System.out.println("x参数类型相差两位,y参数类型相差一位:int,float");
    }
//    x参数类型相差一位,y参数类型相差两位
    static void typeConversion(short x,double y){
        System.out.println("x参数类型相差一位,y参数类型相差两位:short,double");
    }

    public static void main(String[] args){
        byte q = 1;
        long w = 4;
        typeConversion(q,w);
    }
}

想看看到底会执行那个方法,一测试突然发现报错了

报错内容说我的方法模凌两可,猜测是优先度上两个方法是一样的。即(2+1)=(1+2)

把其中一个方法注释掉后,就没报错。

怀着研究到底的心态,于是换了个方式测试

二、一个方法换成两个参数类型都差一位,另一个方法都差两位

public class Test {
//    两个参数类型都相差一位
    static void typeConversion(short x,float y){
        System.out.println("两个参数类型都相差一位:int,float");
    }
//    两个参数类型都相差两位
    static void typeConversion(short x,double y){
        System.out.println("两个参数类型都相差两位:short,double");
    }

    public static void main(String[] args){
        byte q = 1;
        long w = 4;
        typeConversion(q,w);
    }
}

这次没有报错,执行成功,它选择了近一点的,即(1+1)优于(2+2)

 

三、一个方法是参数x的类型相同,参数y类型相差一位;另一个方法是参数x类型相同,参数y类型相差两位

public class Test {
//    参数x类型相同,参数y类型相差一位
    static void typeConversion(byte x,float y){
        System.out.println("参数x类型相同,参数y类型相差一位:byte,float");
    }
//    参数x类型相同,参数y类型相差两位
    static void typeConversion(byte x,double y){
        System.out.println("参数x类型相同,参数y类型相差两位:byte,double");
    }

    public static void main(String[] args){
        byte q = 1;
        long w = 4;
        typeConversion(q,w);
    }
}

这次也没有报错,执行成功,执行了比较相近的那个,即(0+1)优于(0+2)

 

四、再换个方法试一下,方法一中参数x类型相同,参数y类型相差一位;另一个方法参数x类型相差一位,参数y类型相同

public class Test{
//    参数x类型相同,参数y类型相差一位
    static void typeConversion(byte x,float y){
        System.out.println("参数x类型相同,参数y类型相差一位:byte,float");
    }
//    参数x类型相差一位,参数y类型相同
    static void typeConversion(short x,long y){
        System.out.println("参数x类型相差一位,参数y类型相同:short,long");
    }
    public static void main(String[] args){
        byte q = 1;
        long w = 4;
        typeConversion(q,w);
    }
}

可以预见,报了方法模凌两可的错,即

说明优先度上是一样的,把其中一个注释掉就可以了

到这里可以发现,通过显式参数调用两个都需要类型转换的同名方法时,若整体转换等级相等时(多个参数调用未验证),程序会报错,报错原因为 Ambiguous method  (选择困难症。)

 

最后,把所有的方法放到一起,看看哪个优先执行,其中

(1)两个参数类型相同的方法

(2)一个参数类型相同,一个参数类型相差一位

(3)一个参数类型相同,一个参数类型相差两位

(4)参数x类型相差一位,参数y类型相差一位

(5)一个参数类型相差一位,一个参数类型相差两位

(6)两个参数类型都相差两位

public class Test {

//   (1)两个参数类型都相同
    static void typeConversion(byte x,long y){
        System.out.println("两个参数类型都相同:byte,long");
    }

//   (2)参数x类型相同,参数y类型相差一位
    static void typeConversion(byte x,float y){
        System.out.println("参数x类型相同,参数y类型相差一位:byte,float");
    }

//   (3)参数x类型相同,参数y类型相差两位
    static void typeConversion(byte x,double y){
        System.out.println("参数x类型相同,参数y类型相差两位:byte,double");
    }

//   (4)参数x类型相差一位,参数y类型相差一位
    static void typeConversion(short x,float y){
        System.out.println("参数x类型相差一位,参数y类型相差一位:short,float");
    }

//   (5)参数x类型相差一位,参数y类型相差两位
    static void typeConversion(short x,double y) {
        System.out.println("x参数类型相差一位,y参数类型相差两位:short,double");
    }

//   (6)两个参数类型都相差两位
    static void typeConversion(int x,double y) {
        System.out.println("两个参数类型都相差两位:int,double");
    }

    public static void main(String[] args){
        byte q = 1;
        long w = 4;
        typeConversion(q,w);
    }
}

第一次执行,毫无疑问是两个参数类型都相同的方法(1)

把方法(1)注释掉,再执行,毫无疑问执行力方法(2)

再把方法(2)注释掉,令人意外的是,报错了

方法(3)第一个参数类型已经匹配了,没想到优先度跟方法(4)是一样的

猜测一下:只要存在类型转换,均可用以下公式:

可以直接匹配的参数类型记为0,需要向下转换类型时,转换一位记为1,以此类推。

(个人瞎说)先把方法调用优先度记为 pc ,若直接匹配则pc = 0,若需要类型转换,如方法(3),则为pc = (0+2),方法(4),则pc = (1+1),所以方法(3)与方法(4)优先度相同。

 

把其中一个注释掉后,均可执行

注释掉方法(3):

注释掉方法(4):

 

把两个方法都注释掉,往下执行,执行了方法(5)

 

至此,总算理清了今天的想法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值