java中就是没有引用传递,java中只有值传递,因为在传进去值后对值的调用就是对对象的引用。

解决方案 »

  1.   

    我个人理解翻来覆去就两句话:
    1、Java函数调用时,参数传递方式为值传递;
    2、当该参数类型为对象(Object)时,则所传递的值为对象的引用(也可理解为地址)。
    如果你认为Java函数调用有指针传递或引用传递的话,你可以尝试编写这样一个函数来验证:
      public void swap(Object a, Object b);
    效果就是调用后,主调函数的这两个对象互换即可。比如主调函数是:
      String a = "A";
      String b = "B";
      swap(a, b);
      System.out.println(a); // 这里请输出 B
      System.out.println(b); // 这里请输出 A
    当然,你别用反射之类的方式直接去修改常量池啥的招数
      

  2.   

    如果传递的是primities : int, double, short etc, 是值传递。
    如果传递的是对其他object的引用,就是传递的那个object referenceint cube (int a) {<-- pass by value
     return a*a*a
    }Box enLargbox ( Box aBox){ <-- pass by reference
      aBox.setLength (aBox.length * 2);
      aBox.setWidth (aBox.width *2);
      aBox.setHight (aBox.hight *2);
     return aBox;
    }
      

  3.   

    对对,楼上说的对了,java中没有“传引用”这种说法,传递的都是值:
    1:如果是基本数据类型,则传递的是值本身;
    2:如果是引用数据类型,传递独的是地址值。
      

  4.   

    其实不能说Java "无引用传递", 而是Java针对非Primitive的数据类型"自动”进行了引用传递。
    在C++里,假设有一个对象叫做foo, 那么在传递参数的时候://函数fun
    void fun(Foo foo){
          ...
    }
    //传递参数foo给函数fun
    fun(foo);这时候直接这么写,C++编译器就直接是把对象foo按值拷贝传递给了函数fun, 如果要使用按引用传递,则必须写成:fun(&foo);在Java里,由于在语法级别没有引用和指针的概念了,Java虚拟机强制规定,对于Primitive类型(int,float,double,boolean等基础数据类型),在传递参数时按值传递;对继承于Object的对象类型,在传递参数是“必须”使用引用传递,也就是说程序员没有选择的余地,即使想在Java中按值传递对象也是不可能的
      

  5.   

    提醒一个注意点:java中所说“引用”,跟c/c++中的“引用”不是一个概念,c/c++的引用是别名,java的引用是被阉割的指针
      

  6.   

    9楼说的号啊,C中的引用和java中的引用不是一个意思,所指的东西也不一样,java中根本就没有指针的概念,想要理清这两个引用的意思看懂3楼的意思就差不多了,不过如果是初学者的话会很难理解
      

  7.   

    public static void swap(String a, String b) {
    String c = a;
    a = b;
    b = c;
    }
    这是我写的swap,略菜,照此方法测试后输出的是A B,没有输出你说的B A
      

  8.   

    问个问题,
    Java怎么封装对两个int变量的交换? 因为写排序,还是写什么的,经常用到。这个swap如何写?
      

  9.   


    好像是办不到,Java的代码真是啰嗦啊。
      

  10.   

    java中无引用传递,只存在值传递。
    参数是基本数据类型,基本数据类型本身传递,
    参数是引用数据类型,引用数据类型的地址值传递
      

  11.   


    可以把这两个int 放在array里面,返回调换过的array, 如果是给array排序,就得需要写 compareTo() 或者 compare()
      

  12.   

    你就这样理解:
    值传递就是值的拷贝
    引用传递就是引用的拷贝
    比如
    public class Demo{
    public void testInt(int i){
     ++i;
    }
    public void testStrintBuilder(StringBuilder sb){
     sb.append("123");
    }
    public static void main(String[] args){
     Demo demo = new Demo();
     int i = 1;
     demo.testInt(i);
     StringBuilder sb = new StringBuilder();
     demo.testStrintBuilder(sb);
     //打印1,表示参数拷贝
     System.out.println(i);
     //打印123,表示参数没有拷贝,还是之前的引用
     System.out.println(sb.toString);
    }
    }
      

  13.   

    1、java无引用传递,方法的参数(基础类型)在传进去之后,对参数的操作不会修改原值;
    2、对于参数为对象的情况,在传递之前,是复制该对象的引用,在方法内,如果复制的该引用重新赋值了,传参数的那个对象不会被改变;
      

  14.   

    Java里String是值传递的,比较特殊,你用其他对象就不会这样了
      

  15.   

    这是我以前写的一个测试类,大家看看,不包无错import java.util.ArrayList;
    import java.util.List;
    /**
     * 结论:在JAVA中
     *     赋值或传递基本类型时,是通过复制基本类型的值来实现的;
     *     赋值或传递对象时,是通过传递引用(指针)来实现的。
     */
    public class PassParameter {

    public int count = 0;
    public String content = "Hello world";
    public PassParameter pp; public static void main(String[] args) {

    PassParameter p = new PassParameter();
    int i1 = 0;
    int i2 = i1;
    Integer integer = 0;
    String str = "Hello world";
    List<Integer> intListA = new ArrayList<Integer>();
    List<Integer> intListB = new ArrayList<Integer>();
    List<String> strListA = new ArrayList<String>();
    List<String> strListB = strListA;

    /////////////////////////////////////////////////////////

    // 基本类型是通过复制值传递的
    System.out.println("Before: i = " + i1);
    p.addInt(i1);
    System.out.println("After: i = " + i1);

    // 对象是通过传递引用(指针)传递的
    System.out.println("Before: str = " + str);
    p.appendString(str);
    System.out.println("After: str = " + str);

    // 对象是通过传递引用(指针)传递的
    System.out.println("Before: Integer = " + integer);
    p.addInteger(integer);
    System.out.println("After: Integer = " + integer);

    // 成员变量基本类型与普通基本类型无异
    System.out.println("Before: count = " + p.count);
    p.addInt(p.count);
    System.out.println("After: count = " + p.count);

    // 成员String类型变量与普通String类型变量无异
    System.out.println("Before: content = " + p.content);
    p.appendString(p.content);
    System.out.println("After: content = " + p.content);

    // 对象是通过传递引用(指针)传递的
    p.pp = new PassParameter();
    System.out.println("Before: Class = " + p.pp.count);
    p.changeClass(p.pp);
    System.out.println("After: Class = " + p.pp.count);

    // 容器(对象)是通过传递引用(指针)传递的
    System.out.println("Before: List size = " + intListA.size());
    p.addInteger(intListA);
    System.out.println("After: List size = " + intListA.size());
    intListB = intListA;
    p.addInteger(intListB);
    System.out.println("After2: List size = " + intListA.size());

    // 基本类型是通过复制值传递的
    i1 = 10000;
    i2 = i1;
    i1++;
    System.out.println("i1 = " + i1);
    System.out.println("i2 = " + i2);

    // 容器(对象)是通过传递引用(指针)传递的
    strListA.add("a");
    strListB.add("b");
    System.out.println("strListA.size = " + strListA.size());
    System.out.println("strListB.size = " + strListB.size());

    /////////////////////////////////////////////////////////
    }

    public void addInt(int i) {
    i++;
    }

    // 由于传递后对象进行重赋值使引用对象(指针)发生了改变,所以对原对象不会有影响
    public void addInteger(Integer i) {
    i = 10;
    }

    // 由于传递后对象进行重赋值使引用对象(指针)发生了改变,所以对原对象不会有影响
    public void appendString(String str) {
    str = str + " !";
    } public void addInteger(List<Integer> intList) {
    intList.add(1);
    intList.add(2);
    intList.add(3);
    intList.add(4);
    intList.add(5);
    }

    public void changeClass(PassParameter pp) {
    pp.count++;
    }
    }
      

  16.   

    疯狂Java讲义里面如是说:
    Java里方法的参数传递只有一种:值传递。
      

  17.   

    那你随便换个别的对象再试试看吧。C可以对函数参数进行直接交换,是源于其程序能直接操纵指针。
    而Java对指针或地址(估计会有人说Java不存在指针,Anyway)的操纵,是被严格隐藏在JVM内的,是开发者层面所看不到、摸不着、改不动的。
    然后关于引用,可能有人说:有的地方说了,函数参数如果是对象,传递的就是该对象的引用。
    应该说,说这句话的人本身理解应该是正确的,但恐怕不是你所理解的“pass-by-reference”;因为这里强调的是内容,而传递的方式则仍然是“pass-by-value”;所以注意到:“传递的方式”,跟“传递的内容” 是两个不同的命题。
    关于前面讨论了很多的:swap(a, b) 问题,这个就不需要再争论了,Java确实是没法在函数中来实现对主调程序的参数直接进行交换的;当然了,对于可变对象,你仍然可以交换该参数所引用对象的成员属性,但你绝对没法直接交换参数的引用。
    =_= 好绕口令啊,我都担心自己打错字
    回到我原来提出的说法:
    1、Java函数调用时,参数传递方式为值传递;
    ——这里我强调“传递的方式”是啥;
    ——标准教科书只提供两种传递:pass-by-value和pass-by-reference,而Java的函数参数传递绝对不符合后者的特征(主要就是对主调程序的实参本身直接进行操纵),Java中的函数只能对其参数的内容(成员属性)进行操纵;
    2、当该参数类型为对象(Object)时,则所传递的值为对象的引用(也可理解为地址)。
    ——这里我强调“传递的内容”是啥;
    ——对第一个说法的补充,引用本质上也是个值,只要是值,就能被复制,这跟你直接写程序没区别:
    String a = "A"; // 原始的对象"A",及其变量a;先把它理解为主调程序的实参。
    String x = a; // 就复制了一份引用。不是复制了一个对象!把它当成理解成函数的形参就差不多了。
    x = "B"; // 对a变量会产生直接影响么?所以函数的形参也是一个效果。另外有个更权威点的人士给出的解释:
    http://www.javaworld.com/javaqa/2000-05/03-qa-0526-pass.html
    里面提出的主要概念是:"Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'" 这里还有stackoverflow上的问题和回答(以及争论):
    http://stackoverflow.com/questions/40480/is-java-pass-by-reference
      

  18.   



    1、Java函数调用时,参数传递方式为值传递;
    ——这里我强调“传递的方式”是啥;
    ——标准教科书只提供两种传递:pass-by-value和pass-by-reference,而Java的函数参数传递绝对不符合后者的特征(主要就是对主调程序的实参本身直接进行操纵),Java中的函数只能对其参数的内容(成员属性)进行操纵;
    2、当该参数类型为对象(Object)时,则所传递的值为对象的引用(也可理解为地址)。
    ——这里我强调“传递的内容”是啥;
    ——对第一个说法的补充,引用本质上也是个值,只要是值,就能被复制,这跟你直接写程序没区别

    好!
      

  19.   

    针对 911 说另一个权威的解释:
    http://www.javaworld.com/javaqa/2000-05/03-qa-0526-pass.html
    我把他搬过来了,自己也学习下。import java.awt.Point;public class Test1 {
    public static void tricky(Point arg1, Point arg2) {
    arg1.x = 100;
    arg1.y = 100;
    // swap arg1,arg2
    Point temp = arg1;
    arg1 = arg2;
    arg2 = temp;
    } public static void main(String[] args) {
    Point pnt1 = new Point(0, 0);
    Point pnt2 = new Point(0, 0);
    // 0 0
    System.out.println("X: " + pnt1.x + " Y: " + pnt1.y);
    // 0 0
    System.out.println("X: " + pnt2.x + " Y: " + pnt2.y);
    System.out.println(" ");
    tricky(pnt1, pnt2);
    //100 100
    System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
    //0 0
    System.out.println("X: " + pnt2.x + " Y: " + pnt2.y);
    }
    }
    原文:
    The method successfully alters the value of pnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In the main() method, pnt1 and pnt2 are nothing more than object references. When you pass pnt1 and pnt2 to the tricky() method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references.
     
    翻译:
    这个方法成功的改变了pnt1的值,尽管以值传递的形式,但是交换pnt1和ptn2失败了,这是很大的困惑,在main方法里,ptn1和ptn2不过是对象的引用,当你把这两个参数传递给tricky()方法时,
    java用值传递的方式传递引用就像传递了另外一个参数
    //这个翻译不准确,望前辈重翻
    这也就是说传递给方法的引用实际上是对象引用的拷贝。等下有图片说明
      

  20.   

    Figure 1 below shows two references pointing to the same object after Java passes an object to a method. 原文:
    After being passed to a method, an object will have at least two references
    翻译:
    传递给方法之后,对象至少有两个对象的引用继续:
    Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail. As Figure 2 illustrates, the method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call, we need to swap the original references, not the copies. 不翻了,大致意思就是 传递的是拷贝的引用,不是原始的引用。
    有个疑问:
    但是:we need to swap the original references, not the copies. 
    我们需要交换原始的引用,这个怎么交换?
      

  21.   

    比较喜欢“阉割的指针”这个词,很形象。Java函数传递只存在值传一种方式。
    所谓引用传递其实是C++开发者以吸引其它语言的程序转入C++为目的而产生的一个怪胎,它实际的效果与以地址为参数的值传是一样的。C出现以前的高级语言在过程、函数的参数传递中都存在两种传递方式:值传和址传,例如对于Basic的函数sin
    [code=HTML]
      

  22.   

    引用 9 楼  的回复:提醒一个注意点:java中所说“引用”,跟c/c++中的“引用”不是一个概念,c/c++的引用是别名,java的引用是被阉割的指针比较喜欢“阉割的指针”这个词,很形象。Java函数传递只存在值传一种方式。
    所谓引用传递其实是C++开发者以吸引其它语言的程序转入C++为目的而产生的一个怪胎,它实际的效果与以地址为参数的值传是一样的。C出现以前的高级语言在过程、函数的参数传递中都存在两种传递方式:值传和址传,例如对于Basic的函数sina=3.14159265/2
    '1
    b=sin(a)
    '2
    c=sin((a))1处的调用为地址传递(址传),2处的调用为值传。C语言由于可以直接控制指针,所以不再提供指传方式。
    Java虽然不显式支持地址操作,但引用型变量的实质就是指针,对一部分需要用址传方式实现的需求可以用引用变量的值传来间接实现。
      

  23.   


    For a swap to succeed outside of the method call, we need to swap the original references, not the copies.意思是说:如果swap想要能正确发挥作用,我们需要交换其原始(实参)的引用值,而不是副本(形参)的引用值。这句话是对前一句话的补充解释,也就是为什么“Unfortunately, after a method call, you are left with only the unswapped original references.”(不幸的是,在函数调用后,你仍然只能得到之前没有交换过的原始引用)
      

  24.   

    现在做java开发的对指针的理解不深,才会有这样的疑问!!!
      

  25.   

    传递基本数据类型如int,double,等都是值传递,传递Object时,会传递对象的引用
      

  26.   

    没有引用传递,只有值传递。将一个变量传到一个方法中,实际上是将变量的值复制了一份,传进去的。
                    int a = 2;
    shuchu(a); //3
    System.out.println(a); //2
    }

    public static void shuchu(int a) {
    a = 3;
    System.out.println(a);
    }
      

  27.   

    java中不存在引用传递,如果是引用对象的话,则传递的是地址值,基本类型则是值传递
      

  28.   

    学过OC~对于引用传递和值传递的概念又更深刻了
    JAVA里的所谓引用传递类似OC里的
    a = [b copy];
    C代码可以这么理解
    int i=1;
    int *a = &i;
    int j = i;
    int *b = &j;
    相当于new了一个新对象后把新对象(i)的地址赋值给a,新对象(j)的值与b指向对象的值一致。
    所以修改a指向地址的值(i)不会影响到b指向的值(j)而指针传递是
    a = [b retain];
    这时a和b就共用同一个引用(地址)了,JAVA不提供指针传递,所以不存在这个问题
    C代码
    int i = 1;
    int *a = &i;
    int *b = a;但是让我一直很疑惑的是JAVA中数组作为参数的传递
    C中的数组实际上是指向数组首地址的指针,而JAVA又是如何实现的?
      

  29.   

    java 中确实有引用传递,不过需要包
      

  30.   

    感觉LS这位没理解什么是引用传递。话说a = [b copy],a = [b retain]根本不是参数传递的问题,而是赋值的问题吧。
      

  31.   


    大哥你是学C#的吧  ref