什么是java变长参数(java 可变参数是什么)
今天给各位分享什么是java变长参数的知识,其中也会对java 可变参数是什么进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
关于Java多态以及可变形参的问题
首先,运行结果的确是sub。但不是因为“编译器认为 int[] arr和 int...arr是一样的”。而是因为:①可变参数最终会被编译器以数组的方式存下来;然后调用的时候会优先匹配定长参数的方法,只有当定长参数的方法一个都匹配不上了,才去找非定长参数的方法;②你这个上转型之后其实让base这个实例拥有了两个方法,一个是父类的不定长参数,一个是子类的定长参数方法;
传参不报错是因为判断参数是否合法时匹配到了不定长参数那个方法;然后执行时优先匹配到了定长参数方法(可变参和数组存储方式一致)。编译器并不知道什么可变不可变,就单纯的按照规则去校验调用;
对编译器来说,方法名称和参数列表组成了一个唯一键,称为方法签名,JVM通过方法签名决定调用哪种重载方法。
JVM在重载方法中选择合适方法的顺序:
①精确匹配。
②基本数据类型自动转换成更大表示范围。
③自动拆箱与装箱。
④子类向上转型。
⑤可变参数。
你这个上转型实现后,即实现了重写,又实现了一种特殊的重载;而编译器编译时检查参数合法性的时候检查到了可变参的方法(你鼠标挪到调用的地方你会看到,编译器提示的你的方法是父类的可变参方法的,因为此时这个参数不是数组,是匹配不到定长参数的子类方法的);
然后编译好具体执行的时候,编译器哪还知道什么定长不定长,就按照优先级去调用方法,自然就把优先级高的子类定长方法调用到了,不存在什么动态绑定。
这里如果你把子类和父类的参数交换(子类是可变参数,父类是数组)那你的调用就报错了,因为可变参兼容数组,但是数组却不兼容可变参,这样就只形成重写而没有重载,然后上转型后就只能调用父类的方法了。就会报错咯
java 可变参数是什么
java可变参数是1.5版本的新特性,也就是说用户若是想定义一个方法,但是在此之前并不知道以后要用的时候想传几个参数进去,可以在方法的参数列表中写参数类型或者数组名,然后在方法内部直接用操作数组的方式操作。
扩展资料java可变长的形参声明格式:dataType...parameters。
其中,省略号表示数据类型为dataType的parameters参数个数不固定的,可为任意个。此外,在方法调用时,变长形式参数可被替换成1个、2个或多个参数。在编译时,方法的变长参数将被看成具有相同类型的一维数组。
在java语言开发中,从JDK1.5以后,java允许定义形参长度可变的参数从而允许为方法指定数量不确定的形参。
参考资料:java形参长度可变方法-百度百科
java 参数中含有… 是什么意思啊
main方法的签名其实可以这样写:
public static void main(String... args)//方法1
它也可以运行.
并且,如果同时还存在
public static void main(String[] args)//方法2
会报已经存在重复的方法的错误.
由此可见,String... args跟String[] args对于虚拟机来说其实是一回事.
而且,在方法内,通过...传进来的参数的使用方法也跟一个数组完全无二,可以for循环,甚至可以直接转换:
public static void main(String... args)
{
String[] ss=args;
}
但对于程序员来说却还是有差别的.
1.调用
我们只能这样调用方法2:
main(new String[]{});
即,方法2只能接受String数组做参数.
而我们陌生的方法1可强了,用以下参数调用,照单全收:
main();
main(null);
main(null,null);
main(null,null,null);
......
main("a");
main("a","b");
main("a","b","c");
......
main(new String[]{});
(String...匹配String*,而null也可以是一个特殊的String)
2.参数位置
使用...的参数只能是最后一个参数.不然谁知道你调用的时候,点点点匹配到哪个实参?
public static void main(String[] args,int index)//可以
public static void main(String... args,int index)//不行!
3.重载
假设有以下两个方法:
public static void main(String... args)//方法1
public static void main(String a,String... args)//方法3
从语法上来看,这个重载完全没有错误,eclipse也没有报错.但是当调用时使用的参数个数大于这些方法中点点点参数前面的参数个数时,eclipse就会发现这个错误了.很拗口是不是?嘿嘿~还是举例来说吧.以上这两个方法,如果调用时
main();
编译器会认出这个调用的是方法1.但是如果调用时
main("");
编译器就疯了...因为一个String参数,既符合方法1的点点点,也符合方法3的String+点点点,编译器就不知道调用的是哪个方法了.
String[]参数不会有这种问题.
所以重载时要注意,如果点点点参数前面有跟它类型相同的参数...最好的方法,似乎就是换回数组形式了,要么就给方法改个名字吧.
4.遇上泛型加外包
用个实例来说
java.util.Arrays是个工具类,所有方法都是静态的,对数组的操作.里面有个方法asList(T... args),用来把类型T的数组转化成List<T>.
这是个很有用的方法,在绝大多数情况下都能如你所愿.
但是,你可以试试下面的写法
int[] is=...//自定义的数组,或者从什么地方获取来的数组
List<Integer> list=Arrays.asList(is);
很不幸,不要说执行,编译都通不过.错误的意思大概是:
不能将List<int[]>转化成List<Integer>
明白了吧?
你的设想是,把int[]中的每一个元素对应T...中的每一个点,
可编译器不这么想.因为int是原始类型,不是Object的子类.而泛型T隐含的条件是T extends Object.所以编译器不会把每一个int看做T,不会把int[]看做T点点点.虽然java已经支持自动将原始类型封包成外包类,但那是单个的情况.
而数组(不管什么类型)则是一种特殊的类型,是Object的子类,所以编译器觉得整个int[]对应一个T,你调用的方法是asList<int[]>(int[]... args)而不是你想象中的asList<Integer>(Integer...)
java传递参数问题
算机语言给子程序传递参数的方法有两种。
第一种方法是按值传递(call-by-value)。
这种方法将一个参数值(value)复制成为子程序的正式参数。
在Java中,当你给方法传递一个简单类型时,它是按值传递的。因此,接收参数的子程序参数的改变不会影响到该方法之外。例如,看下面的程序:
class Test{
void meth(int i,int j){ i*= 2;j/= 2;
}
}
class CallByValue{
public static void main(String args[]){
Test ob= new Test();
int a= 15,b= 20;
System.out.println("a and b before call:"+
a+""+ b);
ob.meth(a,b);
System.out.println("a and b after call:"+
a+""+ b);
}
}
该程序的输出如下所示:
a and b before call: 15 20
a and b after call: 15 20
可以看出,在meth()内部发生的操作不影响调用中a和b的值。它们的值没在本例中没有变为30和10。
当你给方法传递一个对象时,这种情形就会发生戏剧性的变化,因为对象是通过引用传递的。记住,当你创建一个类类型的变量时,你仅仅创建了一个类的引用。因此,当你将这个引用传递给一个方法时,接收它的参数将会指向该参数指向的同一个对象。这有力地证明了对象是通过引用调用传递给方法的。该方法中对象的改变确实影响了作为参数的对象。例如,考虑下面的程序:
// Objects are passed by reference.
class Test{ int a,b;
Test(int i,int j){a= i;b= j;
}
// pass an object
void meth(Test o){
o.a*= 2;
o.b/= 2;
}
}
class CallByRef{public static void main(String args[]){ Test ob= new Test(15,20);
System.out.println("ob.a and ob.b before call:"+
ob.a+""+ ob.b);
ob.meth(ob);
System.out.println("ob.a and ob.b after call:"+
ob.a+""+ ob.b);
}
}
该程序产生下面的输出:
ob.a and ob.b before call: 15 20
ob.a and ob.b after call: 30 10
正如你所看到的,在这个例子中,在meth()中的操作影响了作为参数的对象。
什么是java变长参数和java 可变参数是什么的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!