您的位置:首页 > 编程语言 > Java开发

Java参数传递,传递引用,传递值浅析

2016-04-07 19:09 453 查看
java的参数传递确实有点绕人,简单研究了一下,

public class Test {

public static void main(String[] args) {
char[] ch = { 'H', 'e', 'l', 'l', 'o' };
change(ch);
System.out.print("ch[]:");
System.out.println(ch); // ch[]:Cello
////传递的是数组首地址,则是传址调用,形参与实参指向同一块内存空间,
///所以形参指向的值改变后,实参的值同样也会改变

changeElement(ch[1]);
System.out.println(ch); // /Cello
////传递的是数组元素,不是地址,则是传值调用,形参的值改变对实参的值无影响

String str1 = "Hello";
String str2 = changStr(str1);
System.out.println("str1:" + str1); // str1:Hello
System.out.println("str2:" + str2); // str2:Cello///返回值赋值给一个新的String对象
/////String对象和基本类型一样,是传值调用,形参的值改变对实参的值无影响

int n = 3;
System.out.println("Before change, n = " + n);// Before change, n = 3
changeData(n);
System.out.println("After changeData(n), n = " + n);// After changeData(n), n= 3
/////String对象和基本类型一样,是传值调用,形参的值改变对实参的值无影响

}
public static void change(char ch[]) {
ch[0] = 'C';
}

public static void changeElement(char c) {
c = 'w';
}
public static String changStr(String str) {
str = "Cello";
return str;
}
public static void changeData(int nn) {
// ///---1
// nn = 10;
// System.out.println("nn="+nn); ///nn=10///第一种情况:形参nn的值是实参n的值都为3,nn后又赋值为10,则nn=10

// //------2
System.out.println("nn=" + nn); // /nn=3 ///第二种情况:不对形参nn赋其他值,则nn=3
}
}
//ch[]:Cello
//Cello
//str1:Hello
//str2:Cello
//Before change, n = 3
//nn=3
//After changeData(n), n = 3
--------------------------------------------------------------------------------------------------------

public class Test3 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);////Before change, sb = Hello

changeData(sb);
System.out.println("After changeData(n), sb = " + sb);////After changeData(n), sb = Hello World!
}

public static void changeData(StringBuffer strBuf) {
strBuf.append("World!");
System.out.println("strBuf = " + strBuf);///strBuf = Hello World!
///strBuf与sb指向同一个StringBuffer,
///若strBuf使StringBuffer内容改变则sb指向的StringBuffer内容也同样改变
}
}
//Before change, sb = Hello
//strBuf = Hello World!
//After changeData(n), sb = Hello World!
------------------------------------------------------------------------------------------------------------

public class Test4 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello ");
System.out.println("Before change, sb = " + sb);////Before change, sb = Hello

changeData(sb);
System.out.println("After changeData(n), sb = " + sb);//After changeData(n), sb = Hello
}
public static void changeData(StringBuffer strBuf) {
StringBuffer sb2 = new StringBuffer("Hi ");
strBuf = sb2;
sb2.append("World!");
System.out.println("sb2 = " + sb2);//sb2 = Hi World!
///strBuf一开始与sb指向同一个StringBuffer,在changeData()中new 了一个新的StringBuffer,
///strBuf = sb2; 则使strBuf指向sb2所指向的新的StringBuffer,strBuf指向的StringBuffer的值改变,对sb所指向的StringBuffer的值无影响
}
}
//Before change, sb = Hello
//sb2 = Hi World!
//After changeData(n), sb = Hello

----------------------------------------------------------------------------------------------------------

class Value {
public int i = 15;
}
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test t = new Test();
t.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);
}
public void second(Value v, int i) {////注意这里的形参v与实参v是两个变量,只是名称相同
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println(v.i + "  " + i);
}

}
//输出:15   0    20   ,有些人不理解??做下变种:
public void second(Value v2, int i) {
i = 0;
v2.i = 20;
Value val = new Value();
v2 = val;
System.out.println(v2.i + "  " + i);
}

这样清晰了很多,

解析看图片:



/////对象,StringBuffer,数组名或数组首地址是传址调用

/////基本类型、String,是传值调用

//关于书上的地址的副本和值的副本那些个人觉得理解起来有些吃力,还是喜欢C里的说法

//String类是个特殊的类,对它的一些操作符是重载的,如:

//String str = “Hello”; 等价于String str = new String(“Hello”);

//-------------------------------

//String str = “Hello”;

//str = str + “ world!”;等价于str = new String((new StringBuffer(str)).append(“ world!”));

//因此,你只要按上面的方法去分析,就会发现String对象和基本类型一样,一般情况下是传值调用

运行环境:win7 64,eclipse kepler,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息