Java中的Pass引用值是什么意思?

时间:2014-07-14 18:06:20

标签: java pass-by-reference

我在网站上研究Java参数时一直看到这一点,但我相信我误解了它。

问题1:Is Java "pass-by-reference" or "pass-by-value"?

问题2:Does Java pass by reference?

人们一直说java引用类型是按值传递的,因此引用本身并没有改变。而且我相信我的困惑来自于"引用自身"是

最初我将其解释为意味着论证所引用的内容,无法以任何方式进行更改或修改,例如添加到列表中的内容。可悲的是,这在某种程度上是错误的并且已经产生了有趣的结果。

当我运行下面的简单代码时,我得到[test1, test2],因此在我的脑海中"参考" list改变了。

import java.util.ArrayList;
import java.util.List;

public class HelloWorld {
    public static void main(String[] args)
    {
        List list = new ArrayList();
        list.add("test1");
        breakStuff(list);
        System.out.println(list.toString());
    }

    public static void breakStuff( List l ) {
        l.add("test2");
    }
}

用我目前的想法"人们的意思(Question 1的答案),当事情发生变化时,他们错了。我不理解或忽视什么?

人们是否提到您可以修改参数引用的数据这一事实,但您无法更改哪些"数据/对象"这个论点是指?

7 个答案:

答案 0 :(得分:2)

public class HelloWorld {
    public static void main(String[] args)
    {
        List list = new ArrayList(); // here list is a "reference" to an "ArrayList" Object
        list.add("test1"); // adding data to the "Object" using the "reference"
        breakStuff(list); // passing the "reference-by-value"
        System.out.println(list.toString()); // printing
    }

    public static void breakStuff( List l ) { // getting the same reference as the original. So l==list is true.
        l.add("test2"); // adding to the same/original object because the reference is same.
l=null; // try this and see what happens. l will point to a "different" object i/e, null while list will be pointing to the original one.
    }
}

答案 1 :(得分:1)

  

人们是否提到您可以修改数据的事实   参数是引用,但你不能改变哪个“数据/对象”   论证是指?

是的,确切地说。例如:

public class HelloWorld {
  public static void main(String[] args)
  {
    List list = new ArrayList();
    list.add("test1");
    breakStuff(list);
    System.out.println(list.toString());
  }

  public static void breakStuff( List l ) {
    l.add("test2");
    l = new ArrayList();
    l.add("foo");
  }
}

是否将原始list更改为包含名为foo的单个元素的新列表。这就是引用按值传递的含义:如果使引用的值副本引用新对象,则原始引用仍引用相同的旧对象。

答案 2 :(得分:0)

这意味着

a = c ;
f(a) { a = b; }
// after we are out of f() here a == c

然而

a.x = 0
f(a) { a.x = 1 }
// after we are out of f() here a.x == 1

答案 3 :(得分:0)

引用指向对象。

你没有改变引用而是对象。

这会改变引用,但它不会更改变量list,因为引用本身会被复制:

public static void breakStuff( List l ) {
        l = new ArrayList();
}

答案 4 :(得分:0)

这意味着当您按值传递引用时,您可以更改其值,但不会发生任何事情。

void passReferenceByValue(List list) {//Java code

    list = new ArrayList(); //We assign new value to reference
    list.add("reftByValue")'

}
void passReference(List* list) {//Non Java code

   list = new ArrayList(); //We assign new value to reference 
   list.add("reference")'
}

温我们测试一下:

  void testPassing() {

    List start = null;

    passByValue(start);

    System.out.println("PassByValue: " + start);

    passReference(start);

    System.out.println("PassReference:" + start);
  }

输出:

PassByValue: null
PassByValue: {reference}

常见误解的原因是实例的变异而不是参考的变化。

   void mutationTest(List list) {

         list.add("mutationOfList"); // In this case we mutate the object that reference point.
   }

答案 5 :(得分:0)

ArrayList对象实际上在堆上。 ArrayList对象始终保持在堆上的位置。

您的参考"列表" (类型列表)是"指向"到堆上的那个对象。或者说另一种方式:" list"包含该对象的内存地址!

将该引用传递给另一个方法时 - 您将在堆上传递该对象的位置。或者换句话说:你将堆上(静止)对象的地址从一个方法传递给另一个方法。

当breakstuff方法使用" l"引用它将修改对象" l"指着。

一个愚蠢的,但通知类比:你在你家旁边山上的一只红鹿上瞄准一支魔术步枪。然后你将步枪发给下一个城镇的朋友。当朋友透过步枪瞄准镜时,步枪立即转动并指向那只红鹿的山丘。

答案 6 :(得分:0)

你熟悉另一种语言吗?比较是有益的。

Java代码:

public class HelloWorld {
    public static void main(String[] args)
    {
        List list = new ArrayList();
        list.add("test1");
        breakStuff(list);
        System.out.println(list.toString());
    }

    public static void breakStuff( List l ) {
        l.add("test2");
    }
}

等效的C ++:

class HelloWorld {
public:
    static void main(String[] args)
    {
        List *list = new ArrayList();
        list->add("test1");
        breakStuff(list);
        System::out->println(list->toString());
    }

    static void breakStuff( List *l ) {
        l->add("test2");
    }
}

你会说在C ++中有引用传递吗?或者全部按值传递?