这回又是一个大难题,放心Java那点儿事说的都是及角旮旯的问题,每次都不会例外的。或许你已经了解Overload了。
上一个简单的例子
说说结果,结果是 int int double long 这体现了参数匹配时的自动加宽原则。
byte 和 short 被加宽至 int
long 直接匹配
float 被加宽至 double
这是最简单的,上回说过装箱的问题,如果在重载时装箱与加宽同时存在就会产生问题。来看下面的例子
说说结果吧,结果很不幸的是long,看来编译器更喜欢加宽而不是装箱。咱们继续摸摸编译器的脾气,看下面的例子,看看编译器会怎么办?
结果先不说,在看看这个例子
这两个考察的是在面对参数不匹配的时候,编译器是先加宽呢还是先装箱呢? 试过了就知道了,上面的例子无法编译,看来编译器更习惯先装箱再加宽,这一点非常重要的。我们仔细分析一下,第一个例子中int先被装箱为Integer然后进行IS-A检测,Integer NOT IS-A Long 所以编译器找不到匹配的方法就会报错。之后的例子中int 被装箱为Integer又因Integer IS-A Object所以可以完成调用并运行。
var-arg与加宽时的问题。在Java5中可以使用多个参数集,其定义方式为(类型... 名)如int... is,在使用中会遵循数组的使用方式。
结果不难猜出是long
int...是一种捕获所有的一种能力,这种能力被Java的设计者安排在了最后。
看完了上面这些内容,我再出一个题目,看看能否做出解答
出现这样的情况,什么加宽啊,装箱啊,什么规则都没有了。在使用method(i)会提示出错。因为编译器无法确定具体调用哪个方法。
除了上面这个情况,一般来说,重写方法的匹配都尊须一下的原则。
基本类型时加宽操作优先于装箱
基本类型时加宽操作优先于var-arg
var-arg是最后的匹配手段
包装类匹配先装箱在加宽
上一个简单的例子
class A {
public static void method(int a) {
System.out.println("int");
}
public static void method(long a) {
System.out.println("long");
}
public static void method(double a) {
System.out.println("double");
}
public static void main(String[] args) {
byte a = 1;
short b = 1;
float c = 24.9f;
long d = 123l;
method(a);
method(b);
method(c);
method(d);
}
}
说说结果,结果是 int int double long 这体现了参数匹配时的自动加宽原则。
byte 和 short 被加宽至 int
long 直接匹配
float 被加宽至 double
这是最简单的,上回说过装箱的问题,如果在重载时装箱与加宽同时存在就会产生问题。来看下面的例子
class A {
public static void method(long a) {
System.out.println("long");
}
public static void method(Integer a) {
System.out.println("Integer");
}
public static void main(String[] args) {
int a = 10;
method(10);
}
}
说说结果吧,结果很不幸的是long,看来编译器更喜欢加宽而不是装箱。咱们继续摸摸编译器的脾气,看下面的例子,看看编译器会怎么办?
class A {
public static void method(Long a) {
System.out.println("Long");
}
public static void main(String[] args) {
int a = 10;
method(10);
}
}
结果先不说,在看看这个例子
class A {
public static void method(Object a) {
System.out.println("Object");
}
public static void main(String[] args) {
int a = 10;
method(10);
}
}
这两个考察的是在面对参数不匹配的时候,编译器是先加宽呢还是先装箱呢? 试过了就知道了,上面的例子无法编译,看来编译器更习惯先装箱再加宽,这一点非常重要的。我们仔细分析一下,第一个例子中int先被装箱为Integer然后进行IS-A检测,Integer NOT IS-A Long 所以编译器找不到匹配的方法就会报错。之后的例子中int 被装箱为Integer又因Integer IS-A Object所以可以完成调用并运行。
var-arg与加宽时的问题。在Java5中可以使用多个参数集,其定义方式为(类型... 名)如int... is,在使用中会遵循数组的使用方式。
class A {
public static void method(long a) {
System.out.println("long");
}
public static void method(int... is) {
System.out.println("int...");
}
public static void main(String[] args) {
int a = 10;
method(10);
}
}
结果不难猜出是long
int...是一种捕获所有的一种能力,这种能力被Java的设计者安排在了最后。
看完了上面这些内容,我再出一个题目,看看能否做出解答
class A{
public static void method(long... ls){
System.out.println("long...");
}
public static void method(Integer... is){
System.out.println("Integer...");
}
public static void main(String[] args){
int i = 10;
method(i);
}
}
出现这样的情况,什么加宽啊,装箱啊,什么规则都没有了。在使用method(i)会提示出错。因为编译器无法确定具体调用哪个方法。
除了上面这个情况,一般来说,重写方法的匹配都尊须一下的原则。
基本类型时加宽操作优先于装箱
基本类型时加宽操作优先于var-arg
var-arg是最后的匹配手段
包装类匹配先装箱在加宽