public class MyTest { /**
 * @param args
 */
public static void main(String[] args) { //初始化
String a="aaaa";
String b=new String("bbbb");

//处理
test1(a);
test2(b);

//输出结果
System.out.println("结果A:"+a);
System.out.println("结果B:"+b);
}
public static void test1(String a)
{
a="111111";
}


public static void test2(String b)
{
b=new String("22222");
}}
[/code]
输出结果
结果A:aaaa
结果B:bbbb
--------------------------------------------------------------------------这里我疑惑 我认为b方法传的是引用 那么 b引用应该指向了2这个对象 ,大家认为呢

解决方案 »

  1.   

    public class MyTest { /** 
    * @param args 
    */ 
    public static void main(String[] args) { //初始化 
    String a="aaaa"; 
    String b=new String("bbbb"); //处理 
    test1(a); 
    test2(b); //输出结果 
    System.out.println("结果A:"+a); 
    System.out.println("结果B:"+b); 

    public static void test1(String a) 

    a="111111"; 

    public static void test2(String b) 

    b=new String("22222"); 
    } } 
      

  2.   

    public static void test1(String a) 

    a="111111"; 

    public static void test2(String b) 

    b=new String("22222"); 

    这两个方法并没有返回值.
    而初始化的a,b当然就不变了.
      

  3.   

    JAVA没有引用传递,只有值传递!
      

  4.   

    Integer Long Char Double String..... 这些对象都是这样的
      

  5.   

    test1和test2中的a,b形式参数是实参的一个copy,你这样做根本不能对实参有任何影响。我一直就反对区分参数传递所谓的“值传”和“引用传递”,这只是表象,这样认为是把String a看做它所指向的实际内容。
    这种理解可以帮助初学者很快记忆。但是应该看到“值传”和“引用传递”的本质。String a;这时在栈内存中有一个变量a,可以认为他是的内容是个地址,而这个地址这时还没有任何意义。
    a = new String("str");这时a变量的地址指向堆内存中一块内存,该内存为"str"的实际所在。
    如果有c/c++基础,这里的a变量其实就是指针。上面的理解了,然后就不要再认为有“值传”和“引用传递”,应该统一为“值传递”,即方法调用,“总”要将实参copy给形参
    ,所以String a的a在test1中被copy了,意味着test1中的a在栈内存中是另一份不同于实参的a,但是都指向同一个堆内存,他们只是名字相同。既然这样,那么你对test1中的a重定向,又怎么会改变实参a呢。
    啰嗦了半天,希望对你有帮助。
      

  6.   

    补充下,
    所谓的基本类型值传递,是因为基本类型的分配是在栈内存中,int a = 1;变量a的内容保存的就是1而非地址,也就不存在指针这样的指向关系,所以方法调用就把这个整体进行了次copy。
      

  7.   

    作用域不同!!!!!!!!!这里的应用不能用C里面的传地址来解释,否则就不叫java了
      

  8.   

    如果2楼说的 
    一个引用只能指向一个对象,多个引用可以指向同一个对象~!就这么简单!
    的话。。 那么test2传进来的参数应该指向了new String("22222");  对像
      

  9.   

     是引用不 假,但是,在test2里,并没诶有改变全局b的引用,。儿时改变局部参数b的引用
      

  10.   

    是楼主理解错误,b是指向new string("bbbb")的
    请看下面内存分析:
    String b=new String("bbbb"); 
    /*内存布局如下:
    这里创建一个局部变量b,b再stack里开辟一小块空间.同时再head中开辟一块空间是真正的对象String("bbbb"),同时,再stack segement里有一个"bbbb".
    b这个引用指向了对象String("bbbb")*/test2(b); 
    /*这里的内存布局:
    调用方法test2(b),在stack里创建一个局部变量b(注意:不同于上面的b)
    */public static void test2(String b) 

    b=new String("22222"); 

    /*执行方法test2(b)时的内存布局:
    第二次创建的局部变量b赋值为"22222"
    接下来,方法test2执行完毕,stack里为test2创建的局部变量消失,也就是说第二次创建的变量b消失.
    这里第二次创建的b就只是位了迷惑你.并且,test2这个方法相当于什么都没有做.(实际上当然是做了事情的)
    */System.out.println("结果B:"+b); 
    /*这里是要打印b这个引用了,也就是第一次创建的那个局部变量b,它指向head区的String("bbbb").所以打印出来的就是bbbb*/Ok,内存分析一步一步来,分析完再看是很简单的.
      

  11.   

    补充一下关于java程序的内存分布:
    代码区:codesegement,存放代码;
    数据区:datasegement,存放静态变量和字符串变量
    栈:stack,存放局部变量.
    堆:head,存放动态创建的东西,例如new出的东西.另外更正一下,13楼我的回复中第一句内存分析中的最后一句应该是:在datasegement里创建了一个"bbbb"
      

  12.   

    13楼请问public class A 
    {
    public static void main(String[] args) 
    {
    B b=new B(); setAge(b); System.out.println(""+b.sex);
    }
    public void setAge(B myb)
    {
    myb.sex="sunlight";
    }
    }
    class B
    {
    public int sex;
    };按你那样说的话。。 那这个结果又是为什么呢
      

  13.   

    public static void test1(String a)
    {
    a="111111";
    }
    public static void test2(String b)
    {
    b=new String("22222"); 
    a和b不要和
    String a="aaaa";
    String b=new String("bbbb"); 
    看做一样的
    在栈中test1和test2中的a和b实际上可以是任何字符(比如c和d)他门是局部变量,在方法体运行后会消亡
      

  14.   

    a始终指向对象"aaaa"。  这是一个基本的概念。
    如果你在test1(a);中让a指向的对象"aaaa"发生了改变。
    则因为a还是指向"aaaa",此时a指向的对象发生了改变。而在此例中,你根本没有令"aaaa"这个对象发生改变。
    可以去尝试用a指向一个可以改变属性值的对象。再用test1(a);方法去改变这个对象的某些属性,这时应该能发现a指向的东西的发生了变化。 
    但是请务必清楚一件事情,就是a的指向不会因为方法传参而改变。
      

  15.   

    public static void test2(String b) 

    b=new String("22222"); 
    } 这个方法你为什么不能写成public static void test2(String Str) 

    Str=new String("22222"); 
    } 改成这样的话 就是b还是指向原来指向的那个对象。
    str一开始指向b指向的那个的对象,然后通过赋值表达式,改变指向,指向了new String("22222")。
    str不是你的b... 不能因为他们指向一个对象么,就以为他们是一个东西。
    传的时候是str=b;形式传的。至少书的图是这么画的。
    在仔细说,str和b都是变量名吧,这2个名字和引用是映射关系吧。引用再指向对象。是这样么...
      

  16.   

    因为String类型是"值"传递,也可说是引用传递
      

  17.   

    public static void test1(String a) 

    a="111111"; 

    public static void test2(String b) 

    b=new String("22222");   //这里的b不是String b=new String("bbbb"); 的b,所以原来的b里的内容没变

      

  18.   


    分析完之后,概括的说一下,这个例子中,只创建了一个实例,b一直指向这个实例.myb在它所在的那个方法存在的时间存在,并修改了这个实例.然后myb消亡,通过b访问这个实例的sex属性并打印.public class A 
    {
        public static void main(String[] args) 
        {
            B b=new B();
    /*直接分析了,从main()的第一句开始.创建B的一个实例b,内存分布:在栈区分配给b一个空间.在堆区创建一个B的实例.b指向这个实例.*/
            setAge(b);
    /*调用方法setAge(B myb);首先创建一个局部变量(形式参数)myb,把b的值传递给它,这里就相当于让myb指向了b指向的实例.
    进入方法体.myb.sex="sunlight";改变myb指向的实例的sex属性值为sunlight;方法结束,形式参数myb消亡.*/
            System.out.println(""+b.sex);
    /*System.out.println(""+b.sex);输出b.sex的值.b指向的实例还是那个实例,只不过在上面的方法中,那个实例的sex属性值被改变了,并且由于改变的是实例,所以myb的消亡没有影响这个改变的事实.所以b的sex属性也就是方法setAge()改变后的值.也就是说打印出的结果是sunlight;*/
        }
        public void setAge(B myb)
        {
            myb.sex="sunlight";
        }
    }
    class B
    {
        public int sex;
    };
      

  19.   

       大家说了这么多,我来说说我的看法;
       
    package com.j2se.myproblem;
    public class GiveAddressOrValue {
     
        public static void main(String args[]) 
        { 
           char[] ch = new char[]{'1','2','3'};
           String name = "ruby";
           Demo demo = new Demo("java");
           run(ch,name,demo);
           System.out.println(ch);
           System.out.println(name);
           System.out.println(demo);
        } 
        
        public static void run(char[] ch,String name,Demo de){
         ch = new char[]{'a','b'};
        
         name = "solejava";
        
         de.setName("oracle");      //使用这句,会改变main中demo的状态
        
         //de = new Demo("oracle"); //使用该句,依然不会改变main中的demo状态
        }  
    }
    class Demo{
    private String name;
    public Demo(String name){
    this.name = name;
    }
    public void setName(String name){
    this.name = name;
    }
    @Override
    public String toString() {
    return this.name;
    }
    }
      /***运行结果:
        123
        ruby
        oracle
       
      **/   
     我想说的是,其实所有的方法调用传递的都是值传递,也就是说方法的形参就是实参的一个副本而已,关键在于形参和实参是什么类型的,如果形参是对象引用类型,那么传递的就是实参的一个对象副本。
     
     相信大家在看到上面的demo和de之后,及其在方法执行之后对各自的影响。其余就不多说了,大家自己试试就知道了。
      

  20.   

    public static void test1(String a

          a="111111"; 

    public static void test2(String b

          b=new String("22222"); 
    }
    在这两个方法中的变量a,b并不是类的成员变量,而是这个方法的局部变量,在上面红色部色定义的.所以在方法内部即使改变了a,b的引用,当这两个方法调用完之后,这两个局部变量在栈空间中分配的空间就消失了.
    而在输出时:
    System.out.println("结果A:"+a); 
    System.out.println("结果B:"+b);
    a,b为类的成员变量和这个类似
    class A {
       int a;
       int b;
         A(int a,int b){
           this.a = a;
           this.b = b;
        }
    }
    如果在构造方法中不写this,那就是把局部变量的值a给局部变量a
      

  21.   

    stirng是引用类型 按道理来说 作为传递参数进入到函数中执行 内容应该改变 但是string只读 不可写 所以对string重新赋值 就是新在内存中生成了一个string对象 与你最终输出的对象已经不是一个了 所以你看到的值没有改变