package com.test;public class Test {
public static void main(String[] args) {
String a = "abc";
String[] b = {"a","b","c"};
change(a,b);
System.out.println(a);
System.out.println(b[0]+b[1]+b[2]);
}
public static void change(String a,String[] b){
a="123";
b[0]="A";
}}
结果是:
abc
Abc
请问为什么String a 的值没被改变,而数字 b[0]的值却改变了??
public static void main(String[] args) {
String a = "abc";
String[] b = {"a","b","c"};
change(a,b);
System.out.println(a);
System.out.println(b[0]+b[1]+b[2]);
}
public static void change(String a,String[] b){
a="123";
b[0]="A";
}}
结果是:
abc
Abc
请问为什么String a 的值没被改变,而数字 b[0]的值却改变了??
解决方案 »
- 一个自己写的2进制,8进制,16进制和10进制互相转换的代码(没有输入检查)
- 新手求助
- 如何在主函数和其他函数之间传递不定长的数组?
- JPanel相关问题编译出错,大家看看
- swt如何实现awt中的color.darker()和color.brighter()
- 大家帮个忙:关于下载NetBeans IDE的。在线等~谢谢!! (2)
- 奇怪的问题,为什么我的画面出不来?
- 帮忙看一下这个程序,错误怎么样解决?
- 我开始学java,使用JBuilder4合不合适?
- 读取test.dat文件并重新写入一个文本文件result.txt
- 求一个比较全的java面试题库
- 这个程序可以关闭,怎么设置背景颜色???
就是这样传得是"abc"这个字符串不妨将方法里的a换名为s
"abc"传进来,s="abc",然后,s="123",这里操作的只是方法里的s,由始至终a都没有变,始终都是指向"abc"这个串注意,s="123"不是更改字符串"abc"为"123",而是将s指向另外一个字符串"123",如果"123"这个串不存在,就创建这个字符串
a="123";
b[0]="A";
} 通俗点解释: change函数,对于普通变量a,改变的是a的副本,此副本为change中的局部变量,而对于传过来的数组(或地址)b则是在原来的变量上操作。
a="123";//改变了a的引用
b[0]="A"; //b的引用没有改变,只是改变了引用指向的对象
JAVA资料太多?选中想收藏的文字(图片),右键选“收录到易载”,搞定!
在Thinking in Java中有这样的例子:
so if you want to hold a word or sentence ,you create a String reference:
String s;
也就是说s是一个reference;当把s做为参数的时候,
比如public void static change (String ss){
ss=new String("abc");
}
change(s);
传进去的是reference s的一个副本。你对ss的任意操作都不会改变外部s指向的对象.其实数组也一样,楼主的例子中,如果让b=一个新的数组,外边的数组同样不受影响 ,这里关键的问题是你通过b[0],引用了b所指向的实际对象,当然对象的值会改变了.
下面举个这样的例子:
public class Test {
public static void change(StringBuffer buffer){
buffer.append("world");
buffer=new StringBuffer("no effect!");
}
public static void main(String[] args) {
StringBuffer s=new StringBuffer("Hello ");
System.out.println(s);
change(s);
System.out.println(s);
}
}
输出是 :
Hello
Hello world
很明显,buffer.append()是 对外面引用的对象的操作,所以产生作用,而buffer=new StringBuffer("no effect!")是对buffer这个值的改变,对外面没有影响.
public class Test {
public static void change(String[] s){
s[0]="t";
s=new String[10];
for(int i=0;i<s.length;i++){
s[i]=String.valueOf(i);
}
}
public static void main(String[] args) {
String[] s={"a","b","c"};
System.out.println(s[0]+s[1]+s[2]);
change(s);
System.out.println("After changing.....");
System.out.println(s[0]+s[1]+s[2]);
for(int i=0;i<s.length;i++){
System.out.print(s[i]);
}
System.out.println();
}
}
输出:
abc
After changing.....
tbc
tbc
对象传递给函数时传递的是新的引用。
应为String改变的是新的引用,所以a不变应为String[]改变的是新引用指向的值b[0],所以改变
怎么到这里又按值传递了?
有没有高人给解释下啊
package com.test;
public class Test {
public static void main(String[] args) {
//这里引用a指向对象"abc"
String a = "abc";
String[] b = {"a","b","c"};
//调用方法
change(a,b);
System.out.println(a);
System.out.println(b[0]+b[1]+b[2]);
}
public static void change(String a,String[] b){
//这里的引用a首先指向对象"abc",接着又会指向对象"123",以前那个"abc"仍然被main方法中的a所指向,所以那个a会打印出"abc"
a="123";
//b[0]指向"a",b[1]指向"b",b[2]指向"c",接着b[0]又会指向"A",以前指向的那个"a"在以后的某个时刻会被GC回收掉,所以b[0]+b[1]+b[2]会打印出Abc
b[0]="A";
}
}
例如:
String a = "a";
项把a的值改成 "b";
只有一种方法:a = "b";没有其他任何方法。建议楼主看看final 类的定义和使用。Java库中有很多都是final类,例如Integer
我稍微修改了下这个程序,可以看到在被调用的方法中对象a和b[]在堆中地址的变化。
可以说在change中的参数a,b[]都是局部变量,只是一开始是引用了外层方法中分配的对象,只要对a,b[]重新赋值就等于重新申请了新的堆空间给新的变量,既"123"这个字符串对象是在堆中重新申请了地址空间,之后又把局部变量a的引用改到了"123",所以在a被重新赋值前后其地址是变化了的。原程序等价于:
public class Test {
public static void main(String[] args) {
String a = "abc";
String[] b = {"a","b","c"};
change(a,b);
System.out.println(a);
System.out.println(b[0] + b[1] + b[2]);
} private static void change(String a,String[] b){
String temp = "123";
a = temp;
b[0] = "A";
}
}
####################################################################################我用来验证地址变化情况的程序如下(写得不够简洁,大家见笑了):
public class Test {
public static void main(String[] args) {
System.out.println("In main() ");
String a = "abc";
Addr ad = new Addr(a);
ad.retAddr("a");
String[] b = {"a","b","c"};
ad = new Addr(b);
ad.retAddr("b[]");
ad = new Addr(b[0]);
ad.retAddr("b[0]");
ad = new Addr(b[1]);
ad.retAddr("b[1]");
ad = new Addr(b[2]);
ad.retAddr("b[2]");
change(a,b);
System.out.println(a);
System.out.println(b[0] + b[1] + b[2]);
} private static void change(String a,String[] b){
System.out.println("\nenter change ");
Addr aod = new Addr(a);
aod.retAddr("a");
aod = new Addr(b);
aod.retAddr("b[]");
aod = new Addr(b[0]);
aod.retAddr("b[0]");
aod = new Addr(b[1]);
aod.retAddr("b[1]");
aod = new Addr(b[2]);
aod.retAddr("b[2]");
System.out.println("a = " + a);
System.out.println("b[] = " + b[0] + b[1] + b[2]);
a = "123";
System.out.println("\nreset a");
System.out.println("a = " + a);
aod = new Addr(a);
aod.retAddr("a");
b[0] = "A";
aod = new Addr(b);
aod.retAddr("b[]");
aod = new Addr(b[0]);
aod.retAddr("b[0]");
aod = new Addr(b[1]);
aod.retAddr("b[1]");
aod = new Addr(b[2]);
aod.retAddr("b[2]");
System.out.println("\nreset b[]");
System.out.println("b[] = " + b[0] + b[1] + b[2]);
System.out.println("exit change!\n");
}
private static class Addr {
public Addr(Object o) {
aObj = o;
}
public void retAddr(String s) {
System.out.print("&" + s + " = ");
System.out.println("@" + Integer.toHexString(aObj.hashCode()));
}
private Object aObj;
}} 运行结果:
In main()
&a = @17862
&b[] = @c17164
&b[0] = @61
&b[1] = @62
&b[2] = @63enter change
&a = @17862
&b[] = @c17164
&b[0] = @61
&b[1] = @62
&b[2] = @63
a = abc
b[] = abcreset a
a = 123
&a = @be32&b[] = @c17164
&b[0] = @41
&b[1] = @62
&b[2] = @63reset b[]
b[] = Abc
exit change!abc
Abc############################################################################################我们还可以做个这样的测试:
public class Test {
public static void main(String[] args) {
String a = "abc";
String[] b = {"a","b","c"};
change(a,b);
System.out.println(a);
System.out.println(b[0] + b[1] + b[2]);
} private static void change(String a,String[] b){
a = "123";
String[] temp = {"1","2","3"};
b = temp;
b[0] = "A";
}
} 看看结果是不是:
abc
abc