java 方法传参
这是小弟的第一篇博客,写得不好还请看官见谅哈!
java 有两种数据类型:基本数据类型(int,short,long,byte,float,double,boolean,char),引用数据类型(基本数据类型之外的数组,String,对象等等)。
在方法中传参数有两种方式:值传递和引用传递
先看下面的一个实例。
public class Stu { String name; int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Test { protected static void updateStu(Stu stu) { stu.setAge(5); stu.setName("Li"); //stu=new Stu(); //stu.setAge(5); //stu.setName("Li"); //用上面注释的代码替换掉未注释,修改前后的stu是一样的,即3,zhang } protected static void updateStr(String str) { str=new String("update"); //str="update"; //这两行代码效果一样 } protected static void updateInteger(Integer i) { i=10; } protected static void updateBasic(int i) { i=10; } protected static void updateArray(int[] test) { if(test.length>1) test[0]=10; } protected static void updateCharArray(char[] cs) { cs=new char[3]; cs[0]='a'; cs[1]='b'; cs[2]='c'; } public static void main(String[] args) { Stu stu=new Stu(); stu.setAge(3); stu.setName("Zhang"); System.out.println("1-----------当方法参数为普通对象"); System.out.println("初始值"); System.out.println(stu.getAge()); System.out.println(stu.getName()); updateStu(stu); System.out.println("修改后"); System.out.println(stu.getAge()); System.out.println(stu.getName()); System.out.println("2-----------当方法参数为String"); String str1=new String("haha"); String str2="hehe"; System.out.println("初始值"); System.out.println(str1); System.out.println(str2); updateStr(str1); updateStr(str2); System.out.println("修改后"); System.out.println(str1); System.out.println(str2); System.out.println("3-----------当方法参数为Integer"); Integer integer=new Integer(5); System.out.println("初始值"); System.out.println(integer); updateInteger(integer); System.out.println("修改后"); System.out.println(integer); System.out.println("4-----------当方法参数为八种基本类型"); int t=5; System.out.println("初始值"); System.out.println(t); updateBasic(t); System.out.println("修改后"); System.out.println(t); System.out.println("5-----------当方法参数为整数数组"); int[] test ={1,2,3}; System.out.println("初始值"); System.out.println(test[0]+"--"+test[1]+"--"+test[2]); updateArray(test); System.out.println("修改后"); System.out.println(test[0]+"--"+test[1]+"--"+test[2]); System.out.println("6-----------当方法参数为字符数组"); char[] cs ={'1','2','3'}; System.out.println("初始值"); System.out.println(cs); updateCharArray(cs); System.out.println("修改后"); System.out.println(cs); } }
=======================================输出
1-----------当方法参数为普通对象
初始值
3
Zhang
修改后
5
Li
2-----------当方法参数为String
初始值
haha
hehe
修改后
haha
hehe
3-----------当方法参数为Integer
初始值
5
修改后
5
4-----------当方法参数为八种基本类型
初始值
5
修改后
5
5-----------当方法参数为整数数组
初始值
1--2--3
修改后
10--2--3
6-----------当方法参数为字符数组
初始值
123
修改后
123
根据上面的结果,可以得出这样的结论
1、基本数据类型采用的是值传递,(类似C里面的传值),它不会修改实参的值
2、引用数据类型采用的是引用传递,(类似C里面的传指针),和值传递类似,传的是引用的一份拷贝,而非引用本身(通过下面的例子证实),引用可以理解成JAVA的指针,它指向对象在堆里面分配的首地址。
3、String修改后为什么实参没变,这个我看过很多文章说String就相当于是char[]的包装类。包装类的特质之一就是在对其值进行操作时会体现出其对应的基本类型的性质。
但是小弟有另一番理解:str="update",这句话会有有如下动作,在栈里面查找有没有value="update"的String引用,要是有就将str指向堆里面的该地址,要是没有就会重新创建一个String对象"update",并将str指向该对象在堆中的地址。在上面的实例中,调用updateStr方法,会将str的引用赋给形参str,而在这个方法中str又重新指向了另一个String对象,但是这个过程并没有修改实参所指向的String对象,这个就和updateStu方法一样,只要new了一个新的对象,那么实参指向的对象就不会改变。
public static void main(String[] args) throws Exception { Demo demo=new Demo(5); changeDemo(demo); System.out.println(demo.val); setDemo(demo); System.out.println(demo.val); } public static void changeDemo(Demo demo) { demo=new Demo(6); } public static void setDemo(Demo demo) { demo.setVal(6); } static class Demo { int val; Demo(int val) { this.val=val; } public void setVal(int val) { this.val=val; } }
输出
5 6
从上面的例子可以看出setDemo将形参引用指向了一个新的对象,它的值是6,但是这个并没有改变实参的值,说明函数传递的并非实参引用本身,而是实参引用的一份拷贝。
setValue,通过形参引用来改变实参的值,是因为,此时实参引用和形参引用指向的是同一对象。