public class Example { String str = new String("good"); char[] ch = { 'a', 'b', 'c' };
public static void main(String[] args) { Example example = new Example(); example.change(example.str, example.ch); System.out.print(example.str + " and "); System.out.println(example.ch); }
public static void main(String[] args) { Example example = new Example(); example.change(example.str, example.ch); System.out.print(example.str + " and "); System.out.println(example.ch); }
}result:good and gbc
public class Example { String str = new String("good"); char[] ch = { 'a', 'b', 'c' }; int abc = 12;
public static void main(String[] args) { Example example = new Example(); example.change(example.str, example.ch); System.out.print(example.str + " and "); System.out.println(example.ch); }
}result:good and gbc
public class Example { String str = new String("good"); char[] ch = { 'a', 'b', 'c' }; int[] abc = {1233,12};
public static void main(String[] args) { Example example = new Example(); example.change(example.str, example.ch,example.abc); System.out.print(example.str + " and "); System.out.println(example.ch); System.out.println(example.abc[0]); }
所以,一个个参数是String类型,String是引用类型,str指向一个String对象good,String是final类型,所以方法里的str是str引用的一个拷背(两个str不是同一个对象),因为String是final类型,所以方法里的" test ok";其实是新创建的另一个对象,和"good";不是同一个对象.所以并没有改变原来的值.同理方法里的ch也是ch引用的一个拷背(两个引用不是同一个对象),但是两个引用指向的是同一个对象{ 'a', 'b', 'c' },所以会改变原来的值.
原本对象[A]和副本对象[A]都指向同一块地址,当副本对象[A]被指向了一个new的对象,则副本对象[A]指向地址就变了,而原本对象[A]还是在指向原来的地址。
原本对象ch[]和副本对象ch[]也是指向同一块地址,但是ch[0]是对地址中的值进行操作,所以当ch[0]被改变时,原本对象ch[]和副本对象ch[]指向的同一块地址中记录的值就被改变了。总结一点就是:值改变和地址改变。具体请参考:http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html
这个问题问得好,看看这篇文章你就明白为什么要这样设计了
http://blog.csdn.net/renfufei/article/details/16808775
public static void main(String[] args) {
StringBuilder str1=new StringBuilder("AAA");
StringBuilder str2=new StringBuilder("BBB");
StringBuilder str3=new StringBuilder("CCC");
change(str1,str2,str3);
System.out.println("str1是:"+str1);
System.out.println("str2是:"+str2);
System.out.println("str3是:"+str3);
}
public static void change(StringBuilder str1,StringBuilder str2,StringBuilder str3) {
str3=str1;
str1=str2;
str2=str3;
str1.append("1");
str2.append("2");
}
str1是:AAA2
str2是:BBB1
str3是:CCC最后的结果是str1的副本指向了str2所指的对象,str2和str3的副本都指向了str1所指的对象
谢谢你!
public void change(String str, char ch[]) {
//str.value =" test ok"; //如果这样就可以了,但value是private;
str = " test ok";
ch[0] = 'g';
}
2. java中只有值传递没有引用传递。
记住吧
str1是:AAA2
str2是:BBB1
str3是:CCC最后的结果是str1的副本指向了str2所指的对象,str2和str3的副本都指向了str1所指的对象
谢谢你! 既然str1的副本又指向了新的地址,那岂不是str1的值不会放生变化? 既然str2和str3的副本都指向了str1所指的对象,那为什么str2 和str3 的值不一样?求解,谢谢
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
public static void main(String[] args) {
Example example = new Example();
example.change(example.str, example.ch);
System.out.print(example.str + " and ");
System.out.println(example.ch);
}
public void change(String str, char ch[]) {
str = " test ok";
ch[0] = 'g';
}
}之前也许我表达的不对,我用我的理解给说明一下吧,一步步来。
首先,str和ch都是引用类型,所以
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
其实是一个str引用对象指向它的实际对象“good”;一个ch引用对象指向了它的实际对象{ 'a', 'b', 'c' };(java里所有的都可以叫对象)
str-->"good" ch-->{ 'a', 'b', 'c' }
其次,方法传值传的是值拷背,也就是方法里的参数传到方法内部后,是参数的一个副本。所以public void change(String str, char ch[]) {
str = " test ok";
ch[0] = 'g';
}这里的str(方法)是外面str的一个拷背,ch(方法)是外面ch的一个拷背。因为是拷背,所以指向一样。因此有
str-->"good" ch-->{ 'a', 'b', 'c' }
str(方法)-->"good" ch(方法)-->{ 'a', 'b', 'c' }
最后,在方法里str(方法)这个引用对象又指向了另一个实际对象 str(方法) = " test ok";,所以有
str-->"good" ch-->{ 'a', 'b', 'c' }
str(方法)-->" test ok" ch(方法)-->{ 'a', 'b', 'c' }
而ch(方法)并没有重新指向另一个实际对象,只是对它现在指向的对象的值做了改变,也就是对原来的实际对象的值做了改变。
换句话说,如果方法里加一段代码 ch(方法) = { 'g', 'b', 'c' } 这样 public void change(String str, char ch[]) {
str = " test ok";
ch = { 'a', 'b', 'c' };//加的代码,表示指向另一个实际对象
ch[0] = 'g';
}ch(方法)就和str(方法)一样,指向了另一个实际对象,这时候无论你怎么操作方法里的ch(方法)和str(方法),都不会影响到方法外的ch和str,输出结果就是两个都不变。
总结,前面我说的String是final和这个问题不大,我在这里向楼主和各位大侠道歉。话有点啰索,希望有帮助。
* @param args
*/
public static void main(String[] args) {
StringBuilder str1=new StringBuilder("AAA");
StringBuilder str2=new StringBuilder("BBB");
StringBuilder str3=new StringBuilder("CCC");
change(str1,str2,str3);
System.out.println("str1是:"+str1);
System.out.println("str2是:"+str2);
System.out.println("str3是:"+str3);
}
public static void change(StringBuilder a,StringBuilder b,StringBuilder c) {
c=a;
a=b;
b=c;
a.append("1");
b.append("2");
System.out.println("a是:"+a);
System.out.println("b是:"+b);
System.out.println("c是:"+c);
System.out.println("-------------------------");
}}
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
int abc = 12;
public void change(String str, char ch[]) {
str = " test ok";
ch[0] = 'g';
// char[] ch1 = {'g','g','g'};
// ch = ch1;
}
public static void main(String[] args) {
Example example = new Example();
example.change(example.str, example.ch);
System.out.print(example.str + " and ");
System.out.println(example.ch);
}
}result:good and gbc
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
int abc = 12;
public void change(String str, char ch[]) {
str = " test ok";
// ch[0] = 'g';
char[] ch1 = {'g','g','g'};
ch = ch1;
}
public static void main(String[] args) {
Example example = new Example();
example.change(example.str, example.ch);
System.out.print(example.str + " and ");
System.out.println(example.ch);
}
}result:good and gbc
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
int[] abc = {1233,12};
public void change(String str, char ch[],int[] abc) {
str = str.replace("g", "x");
str = " test ok";
char[] ch1 = {'g','g','g'};
ch = ch1;
ch[0] = '2';
abc[0] = 1235;
}
public static void main(String[] args) {
Example example = new Example();
example.change(example.str, example.ch,example.abc);
System.out.print(example.str + " and ");
System.out.println(example.ch);
System.out.println(example.abc[0]);
}
}当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。
如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。