Java是通过值传递还是通过引用传递或两者兼而有之?

考虑以下案例。

List listOne = new ArrayList(); List listTwo = new ArrayList(); listOne.add(1);I think this happens due to listOne.add(2); listOne.add(3); Collections.reverse(listOne); listTwo = listOne; //listTwo has same reference Collections.reverse(listOne); System.out.println(listOne); //out put [1, 2, 3] System.out.println(listTwo); // same out put 

Java is pass by value, where values (for non primitive types) happen to be references. 我认为这为这种情况提供了java的生存。 老实说为什么java试图避免pass by reference并尝试与some of other languages ? 而java仍然受到引用行为的影响?

编辑:另外请一些人解释上面代码中发生的事情

Java没有受到引用行为的影响,它让他们:)

当你写作

List listOne = new ArrayList <>();

你需要考虑件事:

1)一个变量,它是一块内存,名为listOne

2)堆上的一个对象,是一个ArrayList的实例,它是一个更大的内存块,没有名称

3)listOne变量的值,它不是内存块,而是放在变量listOne的内存中的一组0和1,并且该值也没有名称。

现在,当我们谈论listOne是通过值还是通过引用传递时,我们使用不精确的术语,这会导致误解。 listOne (事物1)根本没有传递,既不是值也不是引用。 传递listOne(thing 3)的值,这样就可以访问ArrayList对象(第2项)。 因此,如果使用名称“listOne”,但是意味着东西3,则通过值传递,如果意味着事情2,则通过参考传递。 在这两种情况下,名称“listOne”不是东西2或东西3的正确名称,但是因为它简短而方便使用。

Java是通过值传递的。实际参数的副本被传递给参数。在原始数据类型的情况下很明显,其中forms参数的变化未在实际参数中显示。

  static void incre(int a) { a++; } public static void main (String a[]) { int c=3; incre(c); System.out.println(c); //still prints 3 } 

在引用的情况下会发生确切的事情,但是创建引用的副本不会创建新对象,它们现在都指向同一个对象。引用所做的更改将在此处反映出来。

 class Demo { int c =2; Demo(int c) { this.c=c; } void incObject (Demo x) { (xc)++; } int show() { return c; } public static void main (String []args) { Demo o = new Demo(1); o.incObject(o); System.out.print(o.show()); //prints 2 } } 
  Collections.reverse(); 

修改后备arrays。 从实施中可以清楚地看出:

  public static void reverse(List list) { int size = list.size(); if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i=0, mid=size>>1, j=size-1; i>1; i 

现在, listOnelistTwo具有相同的引用,指向相同的后备数组。 因此,无论哪个句柄 (listOne或listTwo)修改后备数组,另一个将反映相同的更改。 在你的情况下:

  Collections.reverse(listOne); // backing array has [3,2,1] listTwo = listOne; //listTwo has same reference Collections.reverse(listOne); // backing array has [1,2,3] System.out.println(listOne); //out put [1, 2, 3] System.out.println(listTwo); // same out put 

就价值/参考传递而言。 你自己说的:

Java是按值传递的,其中值恰好是引用。

为什么java试图避免通过引用传递并尝试与其他一些语言不同?

其中一个主要原因是Java(JVM)管理自己的内存。

Collections.reverse(listOne); 通过值传递对listOne (对象)的引用,这是定义“按引用传递”的方式。 除了原语之外的所有东西都以这种方式传递:通过引用。 它并没有试图避免它,它只是与C ++不同,因为它没有明确地使用指针。

编辑:好的,我想我知道你来自哪里。

 private static void changelist(List list) { list.add(4);//This modifies the list object list = new ArrayList();//This modifies the local copy of the reference to the list object list.add(5); } public static void main(String[] args) { List list = new ArrayList(); list.add(1); list.add(2); list.add(3); System.out.println(list);//output is [1,2,3] //This copies the value of the reference. //If you modify the object in the underlying //function, changes will be preserved when you return //However if you modify what the reference points to, //the function will only modify the local copy changelist(list); System.out.println(list);//output is [1,2,3,4] }