重载 装箱 java,关于java:使用var-args的重载方法-与装箱和加宽相结合

当重载包含不匹配参数的方法时,JVM将始终使用带有比参数宽的最小参数的方法。

我已经通过以下两个示例确认了上述内容:

扩展:字节扩展为int

class ScjpTest{

static void go(int x){System.out.println("In Int");}

static void go(long x){System.out.println("In long");}

public static void main (String[] args){

byte b = 5;

go(b);

}

}

装箱:将int装箱为Integer

class ScjpTest{

static void go(Integer x){System.out.println("In Int");}

static void go(Long x){System.out.println("In Long");}

public static void main (String[] args){

int b = 5;

go(b);

}

}

以上两个示例均输出正确的" In Int"。 我很困惑,但是当情况涉及var-args时,如以下示例所示

class ScjpTest{

static void go(int... x){System.out.println("In Int");}

static void go(long... x){System.out.println("In lInt");}

public static void main (String[] args){

byte b = 5;   //or even with:  int b = 5

go(b);

}

}

上面产生了以下错误:

ScjpTest.java:14: reference to go is ambiguous, both method go(int...) in ScjpTest and method go(long...) in ScjpTest match

go(b);

^

1 error

为什么它不应用与先前示例相同的规则? 即将字节扩展为整数,因为它是最小的大于字节的?

在Java 7上,您的最后一个示例工作正常。

var-args语法只是将数组作为参数传递的别名:

foo(int ... arg)等于foo(int[] arg)

但是数组不是分层的。 String[]不是Object[]的子类。完全相同的规则与方法参数有关。因此,编译器无法在传递byte时区分两个接受long[]和int[]的重载方法。

错误。 String []是Object []的子类。 数组在Java中是协变的(但不是泛型)。 看到我的答案:它实际上是旧Java版本中的一个错误,它不起作用。 ziggy的示例在Java 7中确实有效。

...但是实际上,此示例中的作用甚至不是数组继承,而是扩展了原始类型的转换。

正如AlexR所指出的,var-args就像一个数组。基本数组(例如byte[] short[] int[] long[] float[] double[]似乎在内部编译为同一类。这就是为什么您的重载方法不明确的原因。但是,以下代码是完全有效的:

static void go(int... x){System.out.println("In Int");}

static void go(Long... x){System.out.println("In lInt");}

这将成功编译(因为int[]和long[]是不同的类型),并产生输出In Int。

如果您正在为SCJP做准备,我强烈建议您阅读SCJP Sun认证Java 6考试310-065程序员。本书的"重载"部分介绍了混合拳击和var-args的所有技巧。

它实际上在Java 7中有效:对于varargs示例,它也返回" In Int"。我想这只是先前版本中缺少的功能。我不知道您使用的是哪个Java版本,但也许它也适用于Java 6。

但是,我必须说,即使您的第一个示例都起作用(不使用varargs),我也感到很惊讶。我不知道原始的扩大转换。

顺便说一句,如果您改为使用Byte,Integer和Long,则第一个和最后一个示例将失败,因为这些类型之间没有层次结构(只是它们都是Number的子类)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值