public class Test {
private String str = new String("good");
private char[] ch = {'a','b','c'};
public static void main(String[] args) {
Test t = new Test();
t.change(t.str,t.ch);
System.out.println(t.str);
System.out.println(t.ch[0]);
}
public void change(String str,char[] ch){
str = "test ok";
ch[0] = 'g';
}}结果为什么是:good
g
private String str = new String("good");
private char[] ch = {'a','b','c'};
public static void main(String[] args) {
Test t = new Test();
t.change(t.str,t.ch);
System.out.println(t.str);
System.out.println(t.ch[0]);
}
public void change(String str,char[] ch){
str = "test ok";
ch[0] = 'g';
}}结果为什么是:good
g
解决方案 »
- java中title正则表达式,这个错在哪里在,怎么用正则表达式提取弹性体文档中<title></title>之间的文字
- 关于类型转换(int ->char) 怎么编译器不报错阿?
- 没安装jre的电脑能运行JAVA程序么?
- 关于内部类的继承
- treeviewer的一个问题
- JSP 如何通过 native 定义的method调用 dll 文件呢?
- 这个东东怎么解决?
- 怎样实现类似聊天室的自动滚屏??
- 费解的switch
- java,学生一枚,写一个窗体的时候遇到了添加的组件无法显示的问题,请求大神帮忙,代码如下,非常感谢
- java.lang.NullPointerException的问题
- 关于JTable单元格渲染器的问题,请高手帮忙解决,谢谢
Map map = new HashMap(); System.out.println(map.length); addMap(map); System.out.println(map.length);}private void addMap(Map map){
map.put("1","1");
}道理一样的
public void change(String str,char[] ch){
this.str = "test ok";//加个this就是你希望就的那样了
ch[0] = 'g';
}
change里传递的是str的拷贝,在change里把拷贝指向别的东西不好改变原来的值。
比如:
把change方法改为:
public void change(String str,char[] ch){
str = "test ok";
ch[0] = "csdn".toCharArray();
}
你猜结果如何?
原来是什么那就还是什么!
这一句:ch[0] = "csdn".toCharArray();
以改为:ch = "csdn".toCharArray();
常量都存储在池里,比如'g'等;
对象存储在堆里,如"test ok","good",new String();
而引用存储在栈里,如String str=....中的str;而在Java中只有传值,没有传引用,也就是传参数时,并不是将对象的引用传进函数里,
而是复制了一份引用指向该对象的引用,所以,函数对该引用作的改变(str="test ok"),并不会改变原来对象引用的内容,原来的引用还是指向了"good",楼主明白了没呢?这有点绕~
以public void change(String str,char[] ch)为例,
Test.str这个变量指向"good"这个字符串对象
Test.ch这个变量指向ch[]这个数组对象
在调用change函数时,传递的是 Test.str 与 Test.ch这两个变量的拷贝,假设拷贝为str1,ch1
此时的变量指向情况是这样的
Test.str----->"good"<---------str1
Test.ch ----->ch[]数组<--------ch1
在change函数中,str = "test ok";执行完,改变了变量str1的指向
此时的变量指向情况是这样的
Test.str----->"good" str1----->“test ok”
Test.ch ----->ch[]数组<--------ch1
当执行ch[0] = 'g'; 时,由于ch1指向数组就是传入的数组,所以,数组中第一个元素被修改了。
因为 类的成员变量str 这个引用指向的是字符串"good", 在调用change这个方法的时候
将成员变量的str这个地址引用拷贝给change 方法中的引用变量str。这两个str引用都指向了“good” 然后 change方法中将参数str的引用指向了"test ok"
但成员变量的str引用还是指向的good。。 所以打印 system.out.println(t.str) 时候很显然还是goodch是数组的首地址,也是引用。当调用change方法时,将成员属性ch地址同时拷贝给方法中的参数ch。
此时两个ch地址相同,所以你修改其中ch[0]的时候,成员属性中的ch[] 的第0个索引的值也是被修改的(两个指向是一样的)
举例就是说,你的名字叫“张三”,同时你的外号叫“阿三” 阿三和张三都是指向的你。在本题的string str这个参数时,当调用change方法中的str="test ok" 时候,“阿三”这个引用已经不指向你了,而是指向另外的一个人(test ok)。因为常量池中并没有"test ok",所以就创建了一个String对象"test ok"。
此时 张三指向你自己(本例是"good"), 阿三指向另外的一个人(本例中是"test ok")。
系统打印是打印张三的引用,所以还是good
在char[] ch这个参数时,两个引用都是指向同一个内存地址空间的,随便使用哪个引用改变某一个索引的值,另外一个引用所指向的都会改变。 就正如“阿三”身上有三个口袋里分别有三个纸片,分别写着a,b,c,我把张三的第一个口袋的纸片a换成g, 那张三的第一个口袋的纸片是多少呢? 显然是g
显然str不管引用着谁,都没有改变外部的对象。ch变量引用了那个数组对象,然后用[0]操作使得那个数组对象被改变了。
public void change(String str,char[] ch){
str = "test ok";
ch[0] = 'g';
}
方法体里的str\ch是在函数调用准备的时候COPY的引用.并不是传入那个对象的引用
str = "test ok";
这里把COPY的引用改变了 对外部对象没任何影响ch[0] = 'g'
这里是把ch解引用后再改变值 所以改变的是外部对象的内容
不过java里的赋值传递中的值可以是一个变量,也可以是变量地址。
不懂的话,先看看c语言吧。
简单点说吧
public void change(String str,char[] ch){
str = "test ok";
ch[0] = 'g';
}
方法中的 str 和 t.str 其实没有关系, 只是开始的时候恰好都指向一个String对象 "good"
str = "test ok";//这句语句后 str 指向到了 另一个String对象, 而t.str 依然指向原来的String对象 "good"
至于 ch参数其实也是同理的.
方法里的ch参数和 t.ch 也没什么关系, 同样指向一个char[] 对象.
ch[0] = 'g'; //在方法里面对这个对象里面的值进行了修改, 但是并没有指向另外的对象,
如果这句话改成:
ch = new char[3];
ch[0] = 'g';
就无法改变t.ch指向对象的值了.呵呵 说的有点绕, 不过我觉得这个问题还是讲求顿悟的, 希望对lz有帮助
如果改为
public void change(StringBuffer str,char[] ch){
str.clear();
str.append("test");
ch[0] = 'g';
}
那么最后打印会变成test