java基础

lv6917527 2015-08-11 11:51:28
package Integer;

public class OverloadingVarargs
{
static void f(Character... args)
{
System.out.println("first");
for(Character c:args)
{
System.out.print(" "+c);
}
System.out.println();
}
static void f(Integer... args)
{
System.out.println("second");
for(Integer i:args)
{
System.out.print(" "+i);
}
System.out.println();
}
static void f(long... args)
{
System.out.println("thred");
}
public static void main(String[] args) {
f('a','b','c');
f(1);
f(2,1);
f(0);
f(0l);
}
}
如上代码所示,我在调用静态方法f()时候,在main中最后一个f()没有报错,而其他的都报错 了,不知道是为什么,但是我把可变参数直接改成[]数组就对了,这是什么原因。
...全文
262 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuangqingch 2015-08-11
  • 打赏
  • 举报
回复 1
谢谢4楼,补充一点关于方法参数自动装箱的内容。 如之前答复的代码: public void test(int... a) {} public void test(long... a) {} 执行test(1)时,编译期会提示不明确的方法调用异常。 如果现在换成下面这种方式,执行test(1)是否还会有异常。 public void test(Integer... a) {} public void test(Long... a) {} 答案是:NO 原因方法调用传入的"字面量数值",在编译期时默认采用int类型。除非强制指定类型如:1L,1F,(long)1等 所以test(1),在自动装箱时,一定时装箱成Integer对象。所以不会调用test(Long... a)的方法。 自动装箱和自动拆箱,楼主最好是多了解一些。其实在这块内容上,应该挺多人被坑过的。包括我,不信?试下以下代码: Integer a = 127; Integer b = 127; 问题1:System.out.println(a == b); 结果是什么? 再调整下代码 Integer a = 128; Integer b = 128; 问题1:System.out.println(a == b); 结果是什么? 不明白原理的,可以查下基础数据类型的封装类源代码就明白了。还不明白的可追问。
zhuangqingch 2015-08-11
  • 打赏
  • 举报
回复
谢谢2楼,自己的一点见解而已,回答错别字较多,见谅。补充几点: 调用含可变参数的方法时,传入的参数从"指定位置起的所有参数”会被包装成一个数组。 如方法: public static void test(int a, long b, int... c) { System.out.println(c.length); } 执行 test(1,2,3,4,5,6,7,8),会输出6。 所谓"指定位置起的所有参数”,就是除去固定参数外的参数,即: 3~8六个参数编译后,会变成new int[]{3,4,5,6,7,8} 上述描述也可得出之所以要规定可变参数放在最后的原因:使用方法参数由可变转为明确。 另外,可变参数要求放在最后一个参数,也导致,方法定义中最多只允许存在一个可变参数。
anakin_feng 2015-08-11
  • 打赏
  • 举报
回复
因为 f('a','b','c'); f(1); f(2,1); f(0); 这些都没最直接的方法,因为对于f(1);你本是想调用 f(Integer... args),但是这里是对象,所以并不会直接调用,不过1可以转为Integer对象,所以一般也可这样,但是你这里还有个f(long... args),它也可以转为long再调用这个方法,所以它并不知道该调用哪个方法,所以编译并不会通过,但是如果你把f(long... args)改为f(Long... args)以对象为参数就没问题了,按这个现象应该是看这个参数转化的次数来决定调用哪个函数,当次数相同而且有同样的方法就会报错了
metallica-run 2015-08-11
  • 打赏
  • 举报
回复
楼主把基本型和包装型弄混了,把第三个f()方法的参数改为Long就可以了.
傻傻de点点 2015-08-11
  • 打赏
  • 举报
回复
顶楼上的,说的真TM详细
zhuangqingch 2015-08-11
  • 打赏
  • 举报
回复
楼主,java可变参数的底层实现,实际上就是一个数组,简单的证明方式如下: 定义2个方法: public void test(int[] a) {} public void test(int... a) {} 上述代码在编译阶段就提示异常。原因是可变长参数编译后会被转成Int[],也就是会另一个方法定义重复了。 想详细了解可变参数,也可以去看下编译后的JVM指令,具体可百度查询下,这里就不做详述了。 使用可变参数时,需要注意以下3点: 1、如果有明确的方法可调用,会优化选择”已明确的方法“,如果没有明确的方法,才会选择可变参数对应的方法。如下代码: public void test(int a) { System.out.println("A"); } public void test(int... a) { System.out.println("B"); } 执行,test(1),会输出A 2、Java允许存在多个可变参数的方法,但在调用时如果有多个方法可供选择,则会出现编译时间的异常提示(ambiguous method call:不明确的方法调用)。如下代码: public static void test(int... a) {} public static void test(long... a) {} 在执行test(1),2个方法都可以选择。则出现编译期的异常。 像楼主说的,如果传的是数组为何又正常?通过上述描述,相信楼主也能明白其原因: 如果执行test(new int[]{1}),则test(long... a)是调用不到的(方法参数只接收long[]/long/int/short/byte/char),即能找可唯一选择的方法。 3、定义方法参数时,可变参数只能写在最后一个参数位置上,否则编译期会提示异常。

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧