下面是一下段java语言代码, 请大家分析一下输出, 我的结论与上机调试不符合, 不知道错在哪里, 请大家帮我讲解一下!/*public class Example
{
String str=new String("good"); //1, 定义字符串赋值
char[]ch={'a','b','c'}; //2, 字符数组赋值
public static void main(String[] args)
{
Example ex=new Example(); //3, 实例化Example类, 与ex建立索引关系
ex.change(ex.str,ex.ch); //4, 调用change()函数
System.out.print(ex.str+" and ");//8, 输出调用change()后的str and【和and,后面没有换行】
System.out.print(ex.ch); //9, 输出调用change()后的ch 【接着上面】
}
public void change(String str,char ch[]) //5, 传递参数
{
str="test ok"; //6, 给str赋值
ch[0]='g'; //7, 给ch[0]赋值
}
}
*/注: 输出结果是: good and gbc
请问, 为什么不是: test ok and gbc
{
String str=new String("good"); //1, 定义字符串赋值
char[]ch={'a','b','c'}; //2, 字符数组赋值
public static void main(String[] args)
{
Example ex=new Example(); //3, 实例化Example类, 与ex建立索引关系
ex.change(ex.str,ex.ch); //4, 调用change()函数
System.out.print(ex.str+" and ");//8, 输出调用change()后的str and【和and,后面没有换行】
System.out.print(ex.ch); //9, 输出调用change()后的ch 【接着上面】
}
public void change(String str,char ch[]) //5, 传递参数
{
str="test ok"; //6, 给str赋值
ch[0]='g'; //7, 给ch[0]赋值
}
}
*/注: 输出结果是: good and gbc
请问, 为什么不是: test ok and gbc
或者为什么不是: good and abc
对于你的数组,也是同样的原因,ch[0]='g'只是修正了对象的值,所以原对象被改变。
java中所有的参数传递都是按值传递,不像C和C++还有按引用传递在调用change方法时,实参是ex.str和ex.ch,在change方法内部形参str和ch被赋值为ex.str和ex.ch,也就是说局部变量str和ex.str指向同一字符串对象,局部变量ch和ex.ch指向同一字符数组。这时调用str="...",只是将引用指向另一个字符串对象,对于原来的对象的状态没有修改,所有ex.str没有改变。而ch[0]='..'相当于调用了数组的方法,改变了字符数组的内部状态,ex.ch和ch指向同一对象,所以ex.ch被改变了。
{
this.str="test ok"; //6, 给str赋值
this.ch[0]='g'; //7, 给ch[0]赋值
} 你要改变的是ex的str和ch[0],所以你需要在前面加上this.或着ex.
你的代码是是改change方法里的ch[],并不是ex的。
比我讲的会更清楚。
当你像方法传递一个对象的时候其实change是重新在堆中生成的一块空间。
而当你传递的是一个数组的时候实际只在栈中做了改动,他们是共用一块堆中的空间的。
也就是说属性str和参数str是用的两块存储空间,
而属性ch[]和参数ch[]是共用一块存储空间的。
这是我个人的理解,如有错误,欢迎指正。
System.out.println("ch : " + ch.toString());
这两句,这样就清楚了。
你是想说函数/*
change(String str, char[] ch){
str="test ok";
ch[0]='g';
}*/
的函数体中的str="test ok"; 对类对象的str,即ex.str是不可见的, 是不是? //如果想改变此数据需this.str=="test ok";
如果是这样的话,为什么ch[0]='g';又能修改对象的成员呢???
在主函数里,引用是不变的,主函数里的str指向字符串“good”, ch指向数组['a','b', 'c']调用exchange的时候,给exchange传入了另外两个引用楼主虽然给的名字也叫str和ch,但是编译器没有这么做,实际上是做了其他标记的在exchange函数里的str与ch实际上和主函数的str与ch不是一个引用,而是他们都指向了自己的对象这个时候,在exchange函数里执行str = "test ok"; 相当于,让exchange函数里的str 指向了"test ok"字符串,而exchange函数外,main函数里的str依然指向"good"ch[1] ='g'这个是修改了 exchange函数里ch 这个引用的对象(也就是main函数里的['a','b','c'])里的实际值所以,exchange执行完毕之后,main函数打印,str没变,而ch里的变了如果楼主尝试在exchange里,执行ch = ['d','e'];等exchange执行完毕之后,main函数里打印,两个就都没有变
1, 如果函数体内部的str的修改不会影响到对象的成员,被修改的仅仅是形式参数,[this.man="xxx",则对象的成员肯定会被修改].
为什么函数体外的ch[0],却被修改了呢?
2, 如果是从生命周期来看, 则在change函数内部:
man="Chinese"
ch[0]='g';可是,一旦执行完毕后[跳出change函数], str , ch[0] 则会回复原值。
即有:
str="good"
ch[0]='a'
ch[1]='b'
ch[2]='c'
byte
short
int
longfloat
double
char
boolean
String是类, 根本就不是基本数据类型
String str=new String("xxx");才行的。
{
String str=new String("good"); //1, 定义字符串赋值
char[]ch={'a','b','c'}; //2, 字符数组赋值
public static void main(String[] args)
{
Example ex=new Example(); //3, 实例化Example类, 与ex建立索引关系
ex.change(ex.str,ex.ch); //4, 调用change()函数 补充:此步调用change后楼主把实参调用的是str 和 ch的成员变量,
就等于把成员变量str和ch的两个值传到change方法里,这时你change方法里的
变量无论怎么改变,到调用时都会被 ex.change(ex.str,ex.ch)此调用改成成员变量的值。
System.out.print(ex.str+" and ");//8, 输出调用change()后的str and【和and,后面没有换行】
System.out.print(ex.ch); //9, 输出调用change()后的ch 【接着上面】
}
public void change(String str,char ch[]) //5, 传递参数
{
str="test ok"; //6, 给str赋值 //这里把str=“test ok” 改成this.str="test ok";就ok了。
this.str在这里是指这个str是成员变量str 而不是形参str
ch[0]='g'; //7, 给ch[0]赋值
}
}
*/
//我也是新手,我个人观点有错误请大家及时改正 。如果我讲解正确 希望楼主能理解
c/c++中swap(int &a,int &b){int temp=a;a=b;b=temp;} 就是传值和传址的问题,基本数据类型及其对应的封装类和String都只是传值,数组是传址
我问的是: 问什么结果是good and gbc ?
而不是:good and abc ?
c/c++中swap(int &a,int &b){int temp=a;a=b;b=temp;} 就是传值和传址的问题,基本数据类型及其对应的封装类和String都只是传值,数组是传址
害人不浅啊, java中有传地址的吗? 地址就是指针啊(你在什么地方见到java 指针了)
不懂啊:在change()函数体内部, 你可以看到:str=“test ok”, ch[0]='g'
怎么能说字符串就不可以修改呢?只是修改后, 在跳出该函数的时候, 为什么str不能保存“test ok”值,而ch[0]却可以保存'g' 的值。 我想知道为什么???
swap(int a[],int b[]){int temp=a[0];a[0]=b[0];b[0]=temp;}
int a[]={1};
int b[]={2};
swap(a,b);
System.out.println(a[0]+" "+b[0]);
你会发现a和b交换了!!!
你的意思,我当然知道, 你想说:形参的改变不影响实参[传值情况];而形参的改变影响实参[传地址/传指针]
比如下面的代码:int youInt=5
int& myInt=youInt;youInt++; //执行后,youInt==myInt==6
myInt++; //执行后,youInt==myInt==7但是Java是java , 不要拿C++来这里套好不好, 学习java的有几个没有做过C++的。
这是一个创建树结点的代码
public class Node {
private Object data;
private Node next;
public Node(Object data){
this.data=data;
next=null;
}
public Node(Object data,Node next){
this.data=data;
this.next=next;
}
public void setData(Object data){
this.data=data;
}
public Object getData(){
return data;
}
public void setNext(Node next){
this.next=next;
}
public Node getNext(){
return next;
}
public void print(){
System.out.print(data+" ");
while(next!=null){
System.out.print(next.data+" ");
next=next.next;
}
System.out.println();
}
public static void main(String args[]){
Node n=new Node(10);
n.setNext(new Node(20));
n.next.setNext(new Node(30));
n.print();
}
}
哎,他没闲扯啊!"good"就是一个String类! 还有就是str这个String类,只不过他们的数据来源都存放数据为"good"的内存块中!
MyString str = new MyString("hello");
char ch[] = { 'd', 'b', 'c' };public static void main(String args[]) {
Example ex = new Example();
ex.change1(ex.str, ex.ch);
ex.print();
ex.change2(ex.str, ex.ch);
ex.print();
}public void change1(MyString str, char ch[]) {
str = new MyString("world");
ch[0] = 'a';
}public void change2(MyString str, char ch[]) {
str.setStr("world");
ch[0] = 'a';
}public void print(){
System.out.println(str.toString()+"and"+ch[0]);
}
private class MyString{
private String s;
public MyString(String s){
this.s=s;
}
public void setStr(String s){
this.s=s;
}
public String toString(){
return s;
}
}
}如果不喜欢我用传值和传址解释,就看看这代码吧,这两个change方法有什么不同~!我都是按指针的思想来理解的,不好意思跑题了!