今天看了一个树结构的实现,StringBuffer无法正确显示 改成String就好了 有点疑问就写了下面的testpublic class Test {
public static void main(String []args){
int s = 123;
String m = "123";
Ani a = new Ani();
a.change(s);
System.out.println(s);
a.change(m);
System.out.println(m);
StringBuffer t= new StringBuffer("123");
a.change(t);
System.out.println(t);
StringBuffer t2= new StringBuffer("123");
a.change2(t2);
System.out.println(t2);
}
}class Ani{
public void change(int s){
s=123456;
}
public void change(String m){
m+="456";
}
public void change(StringBuffer t){
t.append("456");
}
public void change2(StringBuffer t2){
t2 = new StringBuffer("000");
}
}
结果是:123
123
123456
123
int,String 都没有因为调用方法而改变,觉得是传值。
StringBuffer t调用change改变,觉得应该是传引用。。
StringBuffer t2调用change2赋予参数新的引用,但是打印出来却没有变。
求高手解答Java到底是传值还是传引用?

解决方案 »

  1.   

    1、  如果参数是基本数据类型(int、long等),传值。方法内部改变参数值,外部值不变。2、  如果参数是对象类型,传地址。方法内部改变对象值,外部对象值改变。但是,如果方法内部调用new重新构建参数对象,外部对象仍然记录构造前的对象值。
      

  2.   


    感谢,String应该也不是基本类型,为什么change()后原值未改变?
      

  3.   

    因为String + 的方法会引起String重构.
    试试这个就可以public class transtest { /**
     * @param args
     */
     public static void change(String k){
     k = k.replace('1', 'a');
             
           System.out.println(k);
     //k+="456";
            
        }
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String m = "123";
    change(m);
        System.out.println(m); }}
      

  4.   

    感谢,String应该也不是基本类型,为什么change()后原值未改变?
    回答 :String 不是基本类型 ,一般的String 都在常量池 中的
      

  5.   

    不要意思,我错了.可能的原因只能认为java把String也作为基本类型了
      

  6.   

    ++
    应该是对的,在不同函数中,所有改String的改变可能都要重构String,或者说所有String都是传值的,在这点上,相当于String为基本类了
      

  7.   


    因为方法中new出来的对象是存在堆栈中得,退出方法,那么这个对象也就被释放了,如果参数引用被指向这个被释放的对象上,后果可想而知,所以参数的引用被重置回原来的引用!
      

  8.   

    java里面只有一种传递参数的方法,那就是传值!对于基本类型来说,它的值就是指我们经常指的值,比如 整型: 100,字符窜型:“你好”对于对象来说,它的值就是它这个变量存储的指向堆中类的地址,所以我们应该区分下,其实对象,和对象变量是不同的String s ,s是对象变量,它只存储了一个地址,指向对象的地址
    s指向的那块内存空间才叫对象。
      

  9.   

    Java 应用程序有且仅有的一种参数传递机制,即按值传递。
    StringBuffer t调用change改变,其实是因为Java对于对象,传递的是这个对象引用的副本,但是指向的其实还是这个对象,所以看起来像是传递的引用,但是其实是值。
    对于String,支持6楼,但是不敢肯定。
      

  10.   

    看完这个博客,楼主应该明白了
    http://blog.csdn.net/niuniu20008/article/details/2953785
      

  11.   

    引用thinking in java中的一段话
    2.2 制作本地副本
    稍微总结一下:Java中的所有自变量或参数传递都是通过传递句柄进行的。也就是说,当我们传递“一个对象”时,实际传递的只是指向位于方法外部的那个对象的“一个句柄”。所以一旦要对那个句柄进行任何修改,便相当于修改外部对象。此外:
    ■参数传递过程中会自动产生别名问题
    ■不存在本地对象,只有本地句柄
    ■句柄有自己的作用域,而对象没有
    ■对象的“存在时间”在Java里不是个问题
    ■没有语言上的支持(如常量)可防止对象被修改(以避免别名的副作用)
    若只是从对象中读取信息,而不修改它,传递句柄便是自变量传递中最有效的一种形式。这种做非常恰当;默认的方法一般也是最有效的方法。然而,有时仍需将对象当作“本地的”对待,使我们作出的改变只影响一个本地副本,不会对外面的对象造成影响。许多程序设计语言都支持在方法内自动生成外部对象的一个本地副本(注释①)。尽管Java不具备这种能力,但允许我们达到同样的效果。①:在C语言中,通常控制的是少量数据位,默认操作是按值传递。C++也必须遵照这一形式,但按值传递对象并非肯定是一种有效的方式。此外,在C++中用于支持按值传递的代码也较难编写,是件让人头痛的事情。12.2.1 按值传递
    首先要解决术语的问题,最适合“按值传递”的看起来是自变量。“按值传递”以及它的含义取决于如何理解程序的运行方式。最常见的意思是获得要传递的任何东西的一个本地副本,但这里真正的问题是如何看待自己准备传递的东西。对于“按值传递”的含义,目前存在两种存在明显区别的见解:
    (1) Java按值传递任何东西。若将基本数据类型传递进入一个方法,会明确得到基本数据类型的一个副本。但若将一个句柄传递进入方法,得到的是句柄的副本。所以人们认为“一切”都按值传递。当然,这种说法也有一个前提:句柄肯定也会被传递。但Java的设计方案似乎有些超前,允许我们忽略(大多数时候)自己处理的是一个句柄。也就是说,它允许我们将句柄假想成“对象”,因为在发出方法调用时,系统会自动照管两者间的差异。
    (2) Java主要按值传递(无自变量),但对象却是按引用传递的。得到这个结论的前提是句柄只是对象的一个“别名”,所以不考虑传递句柄的问题,而是直接指出“我准备传递对象”。由于将其传递进入一个方法时没有获得对象的一个本地副本,所以对象显然不是按值传递的。Sun公司似乎在某种程度上支持这一见解,因为它“保留但未实现”的关键字之一便是byvalue(按值)。但没人知道那个关键字什么时候可以发挥作用。
    尽管存在两种不同的见解,但其间的分歧归根到底是由于对“句柄”的不同解释造成的。我打算在本书剩下的部分里回避这个问题。大家不久就会知道,这个问题争论下去其实是没有意义的——最重要的是理解一个句柄的传递会使调用者的对象发生意外的改变。Java 编程语言只有值传递-------java之父说的,够权威吧