1

I keep seeing this when researching Java arguments on the site but I believe I am misunderstanding it.

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

Question 2: Does Java pass by reference?

People keep saying that in java reference types are passed by value, so that the reference itself isn't changed. And I believe my confusion comes from what the "references itself" is.

Originally I interpreted it to mean that what the argument was referring to, couldn't be changed or modified in any way, such as something being added to a list. Sadly this to some degree is wrong and has caused interesting results.

When I run the simple code below I get [test1, test2], so in my mind "the reference" list got changed.

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"); } } 

With my current "idea" of what the people mean (answers to Question 1), they are wrong as things are changing. What am I not understanding or overlooking?

Are the people referring to the fact that you can modify the data the argument is referencing, but you can't change which "data/object" the argument is referring to?

5
  • 2
    You can change the object referenced, but not the reference. Commented Jul 14, 2014 at 18:16
  • 3
    You can mutate an object, if it is mutable (and an ArrayList is mutable), but you cannot make the variable in the caller refer to a different List. The acid test for pass-by-reference is whether you can write a swap(Object a, Object b) method that will switch a and b around in the caller. By the way, you shouldn't use raw types List and ArrayList, but instead List<String> and ArrayList<String>. Commented Jul 14, 2014 at 18:22
  • 1
    This has got to be a duplicate!! 100 times over. Commented Jul 14, 2014 at 18:28
  • A "reference", in Java, has a specific meaning, and is essentially the same as a "pointer" in C. References are what are passed in parameter lists. They cannot be changed by the callee in a way that would be visible to the caller (because they are passed "by value"). This is different from the use of the term "reference" in, say, a textbook, where the "reference" is essentially some external entity (another book, eg). Commented Jul 14, 2014 at 18:35
  • @PeterLawrey Thank you for explaining both sides together. Originally when I read "You can change the object referenced" in the questions linked, I thought they were meaning changing which object is referenced, just to be told later in the answer I can't. Hopefully I can better understand the terminology now :) Commented Jul 14, 2014 at 21:51

7 Answers 7

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. } } 
Sign up to request clarification or add additional context in comments.

Comments

1

Are the people referring to the fact that you can modify the data the argument is referencing, but you can't change which "data/object" the argument is referring to?

Yes, exactly. For example:

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"); } } 

Does not change the original list to be a new list with a single element named foo. This is what it meant by that the reference is passed by value: if you make the value copy of the reference refer to a new object, the original reference still refers to the same, old object.

1 Comment

Thank you, the ambiguity of the original questions and answers misled me. Thank you for clearing that up :)
0

It means

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

However

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

Comments

0

A reference points to an object.

You didn't change the reference but the object.

This would change the reference, but it won't change the variable list because the reference itself gets copied:

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

Comments

0

What this mean is that when you pass reference by value you can change its value and nothing will happen.

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")' } 

Wen we test it:

 void testPassing() { List start = null; passByValue(start); System.out.println("PassByValue: " + start); passReference(start); System.out.println("PassReference:" + start); } 

The output:

PassByValue: null PassByValue: {reference} 

The reason of common misunderstanding is mutation of instance not change of the reference.

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

Comments

0

The ArrayList object is actually on the heap. The ArrayList object always stays where it is on the heap.

Your reference "list" (of type List) is "pointing" to that object on the heap. Or said another way: "list" contains the memory address of that object!

When you pass that reference to another method - you are passing the location of that object on the heap. Or said another way: you are passing the address of the (stationary) object on the heap from one method to another method.

When the breakstuff method uses the "l" reference it will modify the object that "l" points at.

A stupid, but informing analogy: You aim a magic rifle at a red deer on the hill beside your house. You then post the rifle to a friend in the next town. When the friend looks through the rifle sight the rifle immediately turns and points to the hill with the that red deer.

Comments

0

Are you familiar with another language? A comparison would be instructive.

Java code:

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"); } } 

equivalent 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"); } } 

Would you say there is pass by reference here in the C++? Or all pass by value?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.