package PassRef;public class PassRef {
int x;
public static void main (String []args)
{
PassRef obj= new PassRef();
obj.x=5;
change(obj);
System.out.println(obj.x);

int x;
x=5;
change1(x);
System.out.println( x);


}

public static void change(PassRef obj)
{
obj.x=3;
}
public static void change1(int i)
{
i=3;
}
}执行结果是:
3
5说明,对象是引用传递,而普通变量是值传递。为什么

解决方案 »

  1.   

    其实java就是传值,非要分传值传引用是没有什么意义的public static void change(PassRef obj)你这个方法,传递进去的obj其实也是一个值,无非这个值是一个内存地址而已,地址指向一块内存区域,而这个地址是不会变的。obj.x=3;这一行代码修改的不是地址本身,而是地址指向的区域。public static void change1(int i)这个方法,传递的就是i这个整形代表的值,所以不会变如果非要“对象是引用传递,而普通变量是值传递”这么说,那你想着对象是按照引用调用的,而基本类型的变量存的就是本身的值,他们都位于stack中,而对象真正分配的地方是堆,也就是它的引用指向的地方。
      

  2.   

    貌似这个帖子已经讨论过了, 当时我也做了一个总结.  ls说的都没问题.详细的总结如下:传值还是传引用—— java和C函数参数传递解读 
    http://blog.csdn.net/ostrichmyself/archive/2009/10/03/4630976.aspx
      

  3.   

    看了你前面三段,我似乎明白了。但是最后一句话你说,“对象真正分配的地方是堆”,可按照我的理解,应该也是放在stack中。毕竟也没有new 啊
      

  4.   


    PassRef obj= new PassRef();这不是new了么
      

  5.   

    各位大佬,刚才是我眼拙,没看到这个new那么,这两者的差异根源,是不是就在于一个是new的,在堆里;一个是普通变量, 在栈里?
      

  6.   

    查看这里、
    Java堆和栈 内存分配
      

  7.   

    java使用的都是值传递。方法使用的都是对传入值的拷贝;
    分基本数据类型和对象类型:对象类型是copy了那个引用的值,但指向任然是一个对象。
      

  8.   

    上面有说的很好的,java都是传值,传值其实就是拷贝
    而传引用的话定义就是 形参实际上是实参的alias
      

  9.   

    java都是指传递的,哪来的引用传递
    基本类型的是把自己的值给传递过去,本身并不改变的
    而对象的话,分为普通对象和String对象
    普通对象的话,也是值传递,不过传递的是这个对象所在的内存地址,所以如果在方法体内把这个内存地址上的数据给改变了,原来的也会变
    而String对象,虽然是值传递,但真正在方法体内起作用的是拷贝的值,所以原来的值并不改变
    比如 void change(String s){
      s = "123";
    }
    调用方法的时候,change(t);实际上是t=s; t="123";
      

  10.   

    刚才写快了,最后写错了
    调用方法的时候,change(t);实际上是
    s=t; s="123";
    改变的是s,而不是t
      

  11.   

    基本类型比如short,int之类的是传值,对象都是传的引用
      

  12.   

    int类型的是传值,integer类型的是传引用。
    传值我就不说了,传引用是因为它是对象,想要赋值对象,你必须把内存地址传过去,所以要传引用
      

  13.   

    Java中的对象变量并不没有实际包含一个对象,对象变量的值都是对储存在另外一个地方的一个对象的引用。obj.x是一个引用值,你修改引用值无法改变原值,所以依然输出为5。
    而后面你对x进行修改,这个是对原值的修改,所以最后输出3
      

  14.   

    一个值传递,一个对象引用传递。
    第一个,对象obj储存在堆区里,对象内容被改变,对象也被改变。
    第二个,X值存储在栈里,X指向5这个存储空间,操作方法作用只是对参数进行操作,并未改变栈区间X的指向。就像你去洗澡,,你是变量,浴池的功能是让你变干净,并不会把你的皮肤变白从而改变你整个人。
      

  15.   

    楼上朋友的这个比喻嗯,你尽力了!!呵呵,我上面说了,我现在只有这个疑问: 这两者的差异根源,是不是就在于一个是new的,在堆里;一个是普通变量, 在栈里?
      

  16.   

    public class Test {
    public static void main(String[] args) {


    String str2 = new String("sss");
    change1(str2);
    System.out.println(str2); } public static void change1(String s){

    s = "ddd";
    }
    }
    如果对象是传的是地址 为什么这个的结果是: sss
      

  17.   

    算地址,只是s把旧地址抛弃换了新地址
    str2和s是两个变量,在s没改变引用之前,它们的引用是相同的(这里改变的不是引用所指对象的内容)
      

  18.   

    change1()无返回值,传入的参数是int类型的一个拷贝
      

  19.   

    java都是指传递的,哪来的引用传递
    基本类型的是把自己的值给传递过去,本身并不改变的
    而对象的话,分为普通对象和String对象
    普通对象的话,也是值传递,不过传递的是这个对象所在的内存地址,所以如果在方法体内把这个内存地址上的数据给改变了,原来的也会变
    而String对象,虽然是值传递,但真正在方法体内起作用的是拷贝的值,所以原来的值并不改变
      

  20.   

    可以简单的这么理解,实际上原理是这样的:PassRef obj= new PassRef();//在栈里创建一个变量obj,其值为堆里刚创建的PassRef对象的地址
    int x=5; // 在栈里创建一个变量x,其值为5
    change(obj);// 值传递, change方法输入参数被赋值为obj的值(PassRef对象的地址)
    change(x);// 值传递, change方法输入参数被赋值为x的值(5)我觉得,主要根源不是由于参数传递方式引起,而是由于使用对象时采取了类似“引用”的方式:
    obj1 -> A对象,如果 obj2=obj2,则obj2 -> A对象
    不管通过obj1还是obj2修改了A对象,然后再通过obj1或obj2访问A对象时都是被修改后的A对象。
      

  21.   

    上面写错了:obj1 -> A对象,如果 obj2=obj1,则obj2 -> A对象
    不管通过obj1还是obj2修改了A对象,然后再通过obj1或obj2访问A对象时都是被修改后的A对象。