下面是一下段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

解决方案 »

  1.   


    或者为什么不是: good and abc
      

  2.   

    一般来说,Java的方法参数都是值传递,你直接改变参数对象的指向是不能修改原对象的,只有在调用set等修改对象属性的方法时,原对象的值才可能被改变,但对象地址是肯定不会变化的所以你的str在重新赋值之后,仅仅是改变了你的参数str的当前值,而不是类属性str
    对于你的数组,也是同样的原因,ch[0]='g'只是修正了对象的值,所以原对象被改变。
      

  3.   

    看来楼主对java的按值传参不是很熟悉啊
    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被改变了。
      

  4.   

        public void change(String str)   //5, 传递参数
        { 
            this.str="test ok";                    //6, 给str赋值
            this.ch[0]='g';                        //7, 给ch[0]赋值
        } 你要改变的是ex的str和ch[0],所以你需要在前面加上this.或着ex.
    你的代码是是改change方法里的ch[],并不是ex的。
      

  5.   

    这是由于String的特殊性照成的,String具有不变性,其他的对象就可以改变他的值了
      

  6.   

    java参数传递或者叫值传递,网上资料太多了,你百度一下吧。
    比我讲的会更清楚。
      

  7.   

    字符串没有引用传递,数组是引用传递。所以结果是:good and gbc
      

  8.   

    这个其实我觉得用堆栈来理解更简单一些。
    当你像方法传递一个对象的时候其实change是重新在堆中生成的一块空间。
    而当你传递的是一个数组的时候实际只在栈中做了改动,他们是共用一块堆中的空间的。
    也就是说属性str和参数str是用的两块存储空间,
    而属性ch[]和参数ch[]是共用一块存储空间的。
    这是我个人的理解,如有错误,欢迎指正。
      

  9.   

    你可以在change中最后加上  System.out.println("this.ch : " + this.ch.toString());
     System.out.println("ch : " + ch.toString());
    这两句,这样就清楚了。
      

  10.   

    学习了,补充一点。如果想改变的话,可以定义成static,这样就会变成自己想的结果了
      

  11.   


    你是想说函数/*
    change(String str, char[] ch){
    str="test ok";
    ch[0]='g';
    }*/
    的函数体中的str="test ok"; 对类对象的str,即ex.str是不可见的, 是不是? //如果想改变此数据需this.str=="test ok"; 
    如果是这样的话,为什么ch[0]='g';又能修改对象的成员呢???
      

  12.   

    其实这个问题很简单。楼主调用exchange方法的时候,传入的是两个引用
    在主函数里,引用是不变的,主函数里的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函数里打印,两个就都没有变
      

  13.   

    什么意思, 你?我想说明两点:
    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'
      

  14.   

    String 是基本数据类型,在方法的参数中改变了值并不会改变本身的值。
      

  15.   

    基本数据类型只有8中,让我们来念一下它们的名字吧:
    byte
    short
    int
    longfloat
    double
    char
    boolean
      

  16.   


    String是类, 根本就不是基本数据类型
    String str=new String("xxx");才行的。
      

  17.   

    /*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()函数   补充:此步调用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]赋值
        } 

    */
    //我也是新手,我个人观点有错误请大家及时改正 。如果我讲解正确 希望楼主能理解
      

  18.   

    其实这类似swap(int a,int b){int temp=a;a=b;b=temp;}你调用这个函数是不能实现a和b的值交换
    c/c++中swap(int &a,int &b){int temp=a;a=b;b=temp;} 就是传值和传址的问题,基本数据类型及其对应的封装类和String都只是传值,数组是传址
      

  19.   


    我问的是: 问什么结果是good and gbc ?
    而不是:good and abc     ?
      

  20.   

    其实这类似swap(int a,int b){int temp=a;a=b;b=temp;}你调用这个函数是不能实现a和b的值交换
    c/c++中swap(int &a,int &b){int temp=a;a=b;b=temp;} 就是传值和传址的问题,基本数据类型及其对应的封装类和String都只是传值,数组是传址
      

  21.   


    害人不浅啊, java中有传地址的吗? 地址就是指针啊(你在什么地方见到java 指针了)
      

  22.   

    x.ch是一个数组,在调用change(String str,char ch[])时把整个数组引用过来,也就是什么你可以对第进行修改删除等操作,而x.str相当于我给你这值,你知道这个值是什么东西,但你不能对原数值进行修改,懂否?
      

  23.   


    不懂啊:在change()函数体内部, 你可以看到:str=“test ok”, ch[0]='g' 
    怎么能说字符串就不可以修改呢?只是修改后, 在跳出该函数的时候, 为什么str不能保存“test ok”值,而ch[0]却可以保存'g' 的值。 我想知道为什么???
      

  24.   

    说不清楚了,c/c++有学过不?传值和传址的区别自己百度或谷歌下,还是这句话,基本数据类型及其对应的封装类和String都只是传值,数组或其它类传址!
    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交换了!!!
      

  25.   


    你的意思,我当然知道, 你想说:形参的改变不影响实参[传值情况];而形参的改变影响实参[传地址/传指针]
    比如下面的代码:int youInt=5
    int& myInt=youInt;youInt++;  //执行后,youInt==myInt==6
    myInt++;   //执行后,youInt==myInt==7但是Java是java , 不要拿C++来这里套好不好, 学习java的有几个没有做过C++的。
      

  26.   

    我也是从学java开始的,以前也觉得指针什么的和java一点关系都没有,后来很多东西都不是很好理解,就干脆用c的思想来理解了!如果你实在不想用地址什么的去理解,就强记吧!其实意思是相同的!
      

  27.   

    你学了java的数据结构就知道是不是有类似于指针的概念了!
    这是一个创建树结点的代码
    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();
    }
    }
      

  28.   

    ni de 你的第一句话就会产生;两个String的
      

  29.   


    哎,他没闲扯啊!"good"就是一个String类!  还有就是str这个String类,只不过他们的数据来源都存放数据为"good"的内存块中!
      

  30.   

    change1前者,change2后者;前者不变,后者变。前者指向新地址,原地址不变,所以值是不变的;后者是把原地址所指的数据值改变了,所以值变了!
      

  31.   

    public class Example {
    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方法有什么不同~!我都是按指针的思想来理解的,不好意思跑题了!
      

  32.   

    http://blog.sina.com.cn/s/blog_4b622a8e0100c1bo.html
      

  33.   

    少了个this而已,能扯这么久,服了