7742

I always thought Java uses pass-by-reference. However, I read a blog post which claims that Java uses pass-by-value. I don't think I understand the distinction the author is making.

What is the explanation?

0

87 Answers 87

1 2
3
8

There is a very simple way to understand this. Lets's take C++ pass by reference.

#include <iostream>
using namespace std;

class Foo {
    private:
        int x;
    public:
        Foo(int val) {x = val;}
        void foo()
        {
            cout<<x<<endl;
        }
};

void bar(Foo& ref)
{
    ref.foo();
    ref = *(new Foo(99));
    ref.foo();
}

int main()
{
   Foo f = Foo(1);
   f.foo();
   bar(f);
   f.foo();

   return 0;
}

What is the outcome?

1
1
99
99

So, after bar() assigned a new value to a "reference" passed in, it actually changed the one which was passed in from main itself, explaining the last f.foo() call from main printing 99.

Now, lets see what java says.

public class Ref {

    private static class Foo {
        private int x;

        private Foo(int x) {
            this.x = x;
        }

        private void foo() {
            System.out.println(x);
        }
    }

    private static void bar(Foo f) {
        f.foo();
        f = new Foo(99);
        f.foo();
    }

    public static void main(String[] args) {
        Foo f = new Foo(1);
        System.out.println(f.x);
        bar(f);
        System.out.println(f.x);
    }

}

It says:

1
1
99
1

Voilà, the reference of Foo in main that was passed to bar, is still unchanged!

This example clearly shows that java is not the same as C++ when we say "pass by reference". Essentially, java is passing "references" as "values" to functions, meaning java is pass by value.

Sign up to request clarification or add additional context in comments.

5 Comments

Is there an issue in your c++ version where your risking a segfault when Foo(99) goes out of scope but you reference it in your main method?
Indeed. Ah comes from using java for 10 years. But the idea still holds. And I fixed it now.
I think the previous was better because it would compile. I was just curious about the behavior, sorry about that.
This answer only helps for those coming from C++ background who are willing to define "reference" the way you have, according to C++'s definition. That is not always the case.
"What is the outcome?" - Guess a memory leak
8

Java passes primitive types by value and class types by reference

Now, people like to bicker endlessly about whether "pass by reference" is the correct way to describe what Java et al. actually do. The point is this:

  1. Passing an object does not copy the object.
  2. An object passed to a function can have its members modified by the function.
  3. A primitive value passed to a function cannot be modified by the function. A copy is made.

In my book that's called passing by reference.

Brian Bi - Which programming languages are pass by reference?

8 Comments

This answer is completely incorrect and only creates confusion. Java is a pure pass-by-value language. What confuses you is that the value can be a pointer to an object. Pass-by-reference means one would be able to change the identity of an object at the caller's side. E.g. assigning a new object to a method parameter would also affect the pointer that was passed in the code that called the method.
@Dennis Strings are not primitives, they're objects.
It's not about what's "In your book." "Pass by reference" and "Pass by value" are industry standard terms which have very specific definitions. By those definitions Java is "Pass by value" without exceptions.
C++ has true pass by value where it copies all the fields of the object onto the stack. Java doesn't do this so its not pass by value..
@Solubris It's true that Java does not allow passing entire objects to a method, but when you pass primitives or references (i.e. pointers) you are passing them by value. And importantly, you never pass anything by reference.
|
8

A: Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.

Take the badSwap() method for example:

public void badSwap(int var1, int var2)
{
  int temp = var1;
  var1 = var2;
  var2 = temp;
}

When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well. Now, here is where it gets tricky:

public void tricky(Point arg1, Point arg2)
{
  arg1.x = 100;
  arg1.y = 100;
  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);
  System.out.println("X: " + pnt1.x + " Y: " +pnt1.y); 
  System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
  System.out.println(" ");
  tricky(pnt1,pnt2);
  System.out.println("X: " + pnt1.x + " Y:" + pnt1.y); 
  System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  
}

If we execute this main() method, we see the following output:

X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0

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. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.

enter image description here
Figure 1. 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.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.

Comments

8

PT 1: Of Realty Listings

There is a blue, 120 sq-ft (11 m2) "Tiny House" currently parked at 1234 Main St with a nicely manicured lawn & flower bed out front.

A realtor with a local firm is hired and told to keep a listing for that house.

Let's call that realtor "Bob." Hi Bob.

Bob keeps his listing, which he calls tinyHouseAt1234Main, up to date with a webcam that allows him to note any changes to the actual house in real time. He also keeps a tally of how many people have asked about the listing. Bob's integer viewTally for the house is at 42 today.

Whenever someone wants info about the blue Tiny House at 1234 Main St, they ask Bob.

Bob looks up his listing tinyHouseAt1234Main and tells them all about it - the color, the nice lawn, the loft bed and the composting toilet, etc. Then he adds their inquiry to his viewTally. He doesn't tell them the real, physical address though, because Bob's firm specializes in Tiny Houses that could be moved at any time. The tally is now 43.

At another firm, Realtors might explicitly say their listing "points" to the house at 1234 Main St, denoting this with a little * next to it, because they mainly deal with houses that rarely ever move (though presumably there are reasons for doing so). Bob's firm doesn't bother doing this.

Now, of course Bob doesn't physically go and put the actual house on a truck to show it to clients directly - that would be impractical and a ridiculous waste of resources. Passing a full copy of his tally sheet is one thing, but passing around the whole house all the time is costly and ridiculous.

(Aside: Bob's firm also doesn't 3D print new and unique copies of a listed house every single time someone asks about it. That's what the upstart, similarly named web-based firm and its spinoffs do; that's expensive and slower, and people often get the two firms confused, but they're quite popular anyway).

At some other, older firms closer to the Sea, a realtor like Bob might not even exist to manage the listings. Clients might instead consult the Rolodex "Annie" (& for short) for the direct address of the house. Instead of reading off the referenced house details from the listing like Bob does, clients instead get the house address from Annie (&), and go directly to 1234 Main St, sometimes w/no idea what they might find there.

One day, Bob's firm begins offering a new automated service that needs the listing for a house the client is interested in.

Well, the person with that info is Bob, so the client has Bob call up the service and send it a copy of the listing.

jobKillingAutomatedListingService(Listing tinyHouseAt1234Main, int viewTally) Bob sends along ...

The service, on its end, calls this listing houseToLookAt, but really what it receives is an exact copy of Bob's listing, with the exact same VALUEs in it, that refer to the house at 1234 Main St.

This new service also has its own internal tally of how many people have viewed the listing. The service accepts Bob's tally out of professional courtesy, but it doesn't really care and overwrites it entirely with its own local copy anyway. It's tally for today is 1, while Bob's is still 43.

The realty firms call this "pass-by-value" since Bob's passing the current value of his viewTally and his listing tinyHouseAt1234Main. He's not actually passing along the entire physical house, because that's impractical. Nor is he passing the real physical address like Annie(&) would do.

But he is passing a copy of the value of the reference he has to the house. Seems like a silly pedantic difference in some ways, but that's how his firm works ... ..............

PT II: Where things get confusing and dangerous ...

The new automated service, not being all functional and math-oriented like some other trendy financial and scientific firms, can have unforeseen side effects...

Once given a Listing object it allows clients to actually repaint the real house at 1234 Main St, using a remote drone robot fleet! It allows clients to control a robot bulldozer to actually dig up the flower bed! This is madness!!!

The service also lets clients completely redirect houseToLookAt to some other house at another address, without involving Bob or his listing. All of a sudden they could be looking at 4321 Elm St. instead, which has no connection whatsoever to Bob's listing (thankfully they can't do anymore damage).

Bob watches all this on his real-time webcam. Resigned to the drudgery of his sole job responsibility, he tells clients about the new ugly paint job & sudden lack of curb appeal. His listing is still for 1234 Main St., after all. The new service's houseToLookAt couldn't change that. Bob reports the details of his tinyHouseAt1234Main accurately and dutifully as always, until he gets fired or the house is destroyed entirely by The Nothing.

Really the only thing the service can't do with its houseToLookAt copy of the Bob's original listing is change the address from 1234 Main St. to some other address, or to a void of nothingness, or to some random type of object like a Platypus. Bob's listing still always points to 1234 Main St, for whatever it's still worth. He passes its current value around like always.

This bizarre side effect of passing a listing to the new automated service is confusing for people who ask about how it works. Really, what's the difference between the ability to remotely control robots that alter the state of the house at 1234 Main, vs. actually physically going there and wreaking havoc because Annie gave you the address??

It seems like kind of a nitpicky semantic argument if what you generally care about is the state of the house in the listing being copied and passed around, right?

I mean, if you were in the business of actually picking up houses and physically moving them to other addresses (not like mobile or Tiny Homes where that's sort of an expected function of the platform), or you were accessing, renaming, and shuffling entire neighborhoods like some sort of low-level God-playing madman, then maybe you'd care more about passing around those specific address references instead of just copies of the the latest value of the house details...

Comments

7

Simple program

import java.io.*;
class Aclass
{
    public int a;
}
public class test
{
    public static void foo_obj(Aclass obj)
    {
        obj.a=5;
    }
    public static void foo_int(int a)
    {
        a=3;
    }
    public static void main(String args[])
    {
        //test passing an object
        Aclass ob = new Aclass();
        ob.a=0;
        foo_obj(ob);
        System.out.println(ob.a);//prints 5

        //test passing an integer
        int i=0;
        foo_int(i);
        System.out.println(i);//prints 0
    }
}

From a C/C++ programmer's point of view, java uses pass by value, so for primitive data types (int, char etc) changes in the function does not reflect in the calling function. But when you pass an object and in the function you change its data members or call member functions which can change the state of the object, the calling function will get the changes.

2 Comments

You can only define one class per file. This is not including nested and inner classes. Considering this will be something a new programmer will be reading, you should explain this to the user; allowing them to duplicate the code on their machine.
@mrres1 Not entirely correct. You can define only one public top-level class/interface per file. Supporting several classes per file is a remnant from the first Java version, which didn't have nested classes, but it is still supported, though often frowned upon.
7

I tried to simplify the examples above, keeping only the essense of the problem. Let me present this as a story that is easy to remember and apply correctly. The story goes like this: You have a pet dog, Jimmy, whose tail is 12 inches long. You leave it with a vet for a few weeks while you are travelling abroad.

The vet doesn't like the long tail of Jimmy, so he wants to cut it by half. But being a good vet, he knows that he has no right to mutilate other people's dogs. So he first makes a clone of the dog (with the new key word) and cuts the tail of the clone. When the dog finally returns to you, it has the original 12 inch tail in tact. Happy ending !

The next time you travel, you take the dog, unwittingly, to a wicked vet. He is also a hater of long tails, so he cuts it down to a miserable 2 inches. But he does this to your dear Jimmy, not a clone of it. When you return, you are shocked to see Jimmy pathetically wagging a 2 inch stub.

Moral of the story: When you pass on your pet, you are giving away whole and unfettered custody of the pet to the vet. He is free to play any kind of havoc with it. Passing by value, by reference, by pointer are all just technical wrangling. Unless the vet clones it first, he ends up mutilating the original dog.

public class Doggie {

    public static void main(String...args) {
        System.out.println("At the owner's home:");
        Dog d = new Dog(12);
        d.wag();
        goodVet(d);
        System.out.println("With the owner again:)");
        d.wag();
        badVet(d);
        System.out.println("With the owner again(:");
        d.wag();
    }

    public static void goodVet (Dog dog) {
        System.out.println("At the good vet:");
        dog.wag();
        dog = new Dog(12); // create a clone
        dog.cutTail(6);    // cut the clone's tail
        dog.wag();
    }

    public static void badVet (Dog dog) {
        System.out.println("At the bad vet:");
        dog.wag();
        dog.cutTail(2);   // cut the original dog's tail
        dog.wag();
    }    
}

class Dog {

    int tailLength;

    public Dog(int originalLength) {
        this.tailLength = originalLength;
    }

    public void cutTail (int newLength) {
        this.tailLength = newLength;
    }

    public void wag()  {
        System.out.println("Wagging my " +tailLength +" inch tail");
    }
}

Output:
At the owner's home:
Wagging my 12 inch tail
At the good vet:
Wagging my 12 inch tail
Wagging my 6 inch tail
With the owner again:)
Wagging my 12 inch tail
At the bad vet:
Wagging my 12 inch tail
Wagging my 2 inch tail
With the owner again(:
Wagging my 2 inch tail

Comments

7

Java always passes parameters by value.
All object references in Java are passed by value. This means that a copy of the value will be passed to a method. But the trick is that passing a copy of the value also changes the real value of the object.

Please refer to the below example,

public class ObjectReferenceExample {

    public static void main(String... doYourBest) {
            Student student = new Student();
            transformIntoHomer(student);
            System.out.println(student.name);
    }

    static void transformIntoDuleepa(Student student) {
            student.name = "Duleepa";
    }
}
class Student {
    String name;
}

In this case, it will be Duleepa!
The reason is that Java object variables are simply references that point to real objects in the memory heap. Therefore, even though Java passes parameters to methods by value, if the variable points to an object reference, the real object will also be changed.

2 Comments

Running this program should help anyone understand this concept. pastebin.com/VEc8NQcX
In this example you've not copied the Student object, so I think saying "passing a copy of the value also changes the real value of the object" is misleading. The thing that you are copying, and passing-by-value, is the reference to the object. The object stays living on the heap, and there's just one of them. That's why when you use the new reference to mutate the object, you're mutating it for everyone else that has a reference to the object. There's only one object. When the argument of the function is a primitive type, not a reference to an object, it is also copied.
7

Shortest answer :)

  • Java has pass-by-value (and pass-reference-by-value.)
  • C# also has pass-by-reference

In C#, this is accomplished with the "out" and "ref" keywords.

Pass By Reference: The variable is passed in such a way that a reassignment inside the method is reflected even outside the method.

Here follows an example of passing-by-reference (C#). This feature does not exist in Java.

class Example
{
    static void InitArray(out int[] arr)
    {
        arr = new int[5] { 1, 2, 3, 4, 5 };
    }

    static void Main()
    {
        int[] someArray;
        InitArray(out someArray);

        // This is true !
        boolean isTrue = (someArray[0] == 1);
    }
}

See also: MSDN library (C#): passing arrays by ref and out

See also: MSDN library (C#): passing by by value and by reference

Comments

7

Java is only passed by value. There isn't any pass by reference. For example, you can see the following example.

package com.asok.cop.example.task;
public class Example {
    int data = 50;

    void change(int data) {
        data = data + 100;// Changes will be in the local variable
        System.out.println("after add " + data);
        }

    public static void main(String args[]) {
        Example op = new Example();
        System.out.println("before change " + op.data);
        op.change(500);
        System.out.println("after change " + op.data);
    }
}

Output:

before change 50
after add 600
after change 50

as Michael says in the comments:

objects are still passed by value even though operations on them behave like pass-by-reference. Consider void changePerson(Person person){ person = new Person(); } the callers reference to the person object will remain unchanged. Objects themselves are passed by value but their members can be affected by changes. To be true pass-by-reference, we would have to be able to reassign the argument to a new object and have the change be reflected in the caller.

2 Comments

Describing java as "pass-by-value" is highly misleading. For non-primitive types Java uses "pass by value of the reference". "Pass by value" implies the value is copied when passed to a method. It is not, the reference is copied.
Not half the answer.
6

Mr @Scott Stanchfield wrote an excellent answer. Here is the class that would you to verify exactly what he meant:

public class Dog {

    String dog ;
    static int x_static;
    int y_not_static;

    public String getName()
    {
        return this.dog;
    }

    public Dog(String dog)
    {
        this.dog = dog;
    }

    public void setName(String name)
    {
        this.dog = name;
    }

    public static void foo(Dog someDog)
    {
        x_static = 1;
        // y_not_static = 2;  // not possible !!
        someDog.setName("Max");     // AAA
        someDog = new Dog("Fifi");  // BBB
        someDog.setName("Rowlf");   // CCC
    }

    public static void main(String args[])
    {
        Dog myDog = new Dog("Rover");
        foo(myDog);
        System.out.println(myDog.getName());
    }
}

So, we pass from main() a dog called Rover, then we assign a new address to the pointer that we passed, but at the end, the name of the dog is not Rover, and not Fifi, and certainly not Rowlf, but Max.

Comments

6

Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.

Take the badSwap() method for example:

    public void badSwap(int var1, int
 var2{ int temp = var1; var1 = var2; var2 =
 temp; }

When badSwap() returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int to Object, since Java passes object references by value as well. Now, here is where it gets tricky:

public void tricky(Point arg1, Point   arg2)
{ arg1.x = 100; arg1.y = 100; 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); System.out.println("X:
 " + pnt1.x + " Y: " +pnt1.y);

     System.out.println("X: " + pnt2.x + " Y:
 " +pnt2.y); System.out.println(" ");

     tricky(pnt1,pnt2);
 System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);

     System.out.println("X: " + pnt2.x + " Y: " +pnt2.y); }

If we execute this main() method, we see the following output:

X: 0 Y: 0 X: 0 Y: 0 X: 100 Y: 100 X: 0 Y: 0

The method successfully alters the value ofpnt1, even though it is passed by value; however, a swap of pnt1 and pnt2 fails! This is the major source of confusion. In themain() method, pnt1 and pnt2 are nothing more than object references. When you passpnt1 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. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.

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.

Comments

5

The bottom line on pass-by-value: the called method can't change the caller's variable, although for object reference variables, the called method can change the object the variable referred to. What's the difference between changing the variable and changing the object? For object references, it means the called method can't reassign the caller's original reference variable and make it refer to a different object, or null.

I took this code and explanation from a book on Java Certification and made some minor changes.
I think it's a good illustration to the pass by value of an object. In the code below, reassigning g does not reassign f! At the end of the bar() method, two Foo objects have been created, one referenced by the local variable f and one referenced by the local (argument) variable g.

Because the doStuff() method has a copy of the reference variable, it has a way to get to the original Foo object, for instance to call the setName() method. But, the doStuff() method does not have a way to get to the f reference variable. So doStuff() can change values within the object f refers to, but doStuff() can't change the actual contents (bit pattern) of f. In other words, doStuff() can change the state of the object that f refers to, but it can't make f refer to a different object!

package test.abc;

public class TestObject {

    /**
     * @param args
     */
    public static void main(String[] args) {
        bar();
    }

    static void bar() {
        Foo f = new Foo();
        System.out.println("Object reference for f: " + f);
        f.setName("James");
        doStuff(f);
        System.out.println(f.getName());
        //Can change the state of an object variable in f, but can't change the object reference for f.
        //You still have 2 foo objects.
        System.out.println("Object reference for f: " + f);
        }

    static void doStuff(Foo g) {
            g.setName("Boo");
            g = new Foo();
            System.out.println("Object reference for g: " + g);
        }
}


package test.abc;

public class Foo {
    public String name = "";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Note that the object reference has not changed in the console output below:

Console output:

Object reference for f: test.abc.Foo@62f72617

Object reference for g: test.abc.Foo@4fe5e2c3

Boo Object reference for f: test.abc.Foo@62f72617

Comments

5

Java passes references to objects by value.

So if any modification is done to the Object to which the reference argument points it will be reflected back on the original object.

But if the reference argument point to another Object still the original reference will point to original Object.

Comments

5

There is a workaround in Java for the reference. Let me explain by this example:

public class Yo {
public static void foo(int x){
    System.out.println(x); //out 2
    x = x+2;
    System.out.println(x); // out 4
}
public static void foo(int[] x){
    System.out.println(x[0]); //1
    x[0] = x[0]+2;
    System.out.println(x[0]); //3
}
public static void main(String[] args) {
    int t = 2;
    foo(t);
    System.out.println(t); // out 2 (t did not change in foo)

    int[] tab = new int[]{1};
    foo(tab);
    System.out.println(tab[0]); // out 3 (tab[0] did change in foo)
}}

I hope this helps!

1 Comment

To understand this, one needs to understand that unlike in many languages in Java an array is an Object itself.
5

Java passes everything by value!!

//create an object by passing in a name and age:

PersonClass variable1 = new PersonClass("Mary", 32);

PersonClass variable2;

//Both variable2 and variable1 now reference the same object

variable2 = variable1; 


PersonClass variable3 = new PersonClass("Andre", 45);

// variable1 now points to variable3

variable1 = variable3;

//WHAT IS OUTPUT BY THIS?

System.out.println(variable2);
System.out.println(variable1);

Mary 32
Andre 45

if you could understand this example we r done. otherwise, please visit this webPage for detailed explanation:

webPage

1 Comment

This actually doesn't explain anything in regards to potential by ref/by val property of Java.
5

It seems everything is call by value in java as i have tried to understand by the following program

Class-S

class S{
String name="alam";
public void setName(String n){
this.name=n; 
}}

Class-Sample

    public class Sample{
    public static void main(String args[]){
    S s=new S();
    S t=new S();
    System.out.println(s.name);
    System.out.println(t.name);
    t.setName("taleev");
    System.out.println(t.name);
    System.out.println(s.name);
    s.setName("Harry");
    System.out.println(t.name);
    System.out.println(s.name);
    }}

Output

alam

alam

taleev

alam

taleev

harry

As we have define class S with instance variable name with value taleev so for all the objects that we initialize from it will have the name variable with value of taleev but if we change the name's value of any objects then it is changing the name of only that copy of the class(Object) not for every class so after that also when we do System.out.println(s.name) it is printing taleev only we can not change the name's value that we have defined originally, and the value that we are changing is the object's value not the instance variable value so once we have define instance variable we are unable to change it

So i think that is how it shows that java deals with values only not with the references

The memory allocation for the primitive variables can be understood by this

Comments

5

I'd say it in another way:

In java references are passed (but not objects) and these references are passed-by-value (the reference itself is copied and you have 2 references as a result and you have no control under the 1st reference in the method).

Just saying: pass-by-value might be not clear enough for beginners. For instance in Python the same situation but there are articles, which describe that they call it pass-by-reference, only cause references are used.

Comments

5

For simplicity and verbosity

It’s pass reference by value:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // We pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // Change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

1 Comment

Sure, the confusion comes from the fact, that outside the Java community there is other semantics and verbose "Java is not God"
5

First let's understand memory allocation in Java: The stack and heap are the part of memory that JVM allocates for different purposes. The stack memory is preallocated to s thread, when it is created, and therefore a thread cannot access the stack of other thread. But the heap is available to all threads in a program.

For a thread, the stack stores all local data, metadata of program, primitive type data and object reference. And, the heap is responsible for storage of the actual object.

Book book = new Book("Effective Java");

In the above example, the reference variable is "book" which is stored on the stack. The instance created by the new operator (new Book("Effective Java")) is stored on the heap. The ref variable "book" has the address of the object allocated on the heap. Let's say the address is 1001.

Enter image description here

Consider passing a primitive data type, i.e. int, float, double, etc.

public class PrimitiveTypeExample {
    public static void main(string[] args) {
       int num = 10;
       System.out.println("Value before calling method: " + num);
       printNum(num);
       System.out.println("Value after calling method: " + num);
    }
    public static void printNum(int num){
       num = num + 10;
       System.out.println("Value inside printNum method: " + num);
    }
}

The output is: Value before calling method: 10 Value inside printNum method: 20 Value after calling method: 10

int num =10; -> this allocates the memory for "int" in Stack of the running thread, because, it is a primitive type. Now when printNum(..) is called, a private stack is created within the same thread. When "num" is passed to this method, a copy of "num" is created in the method stack frame.

num = num+10; -> this adds 10 and modifies the the int variable within the method stack frame. Therefore, the original num outside the method stack frame remains unchanged.

Consider, the example of passing the object of a custom class as an argument.

Enter image description here

In the above example, the ref variable "book" resides in the stack of the thread executing the program, and the object of class Book is created in the heap space when the program executes new Book(). This memory location on the heap is referred by "book". When "book" is passed as a method argument, a copy of "book" is created in a private stack frame of the method within the same stack of the thread. Therefore, the copied reference variable points to the same object of class "Book" on the heap.

Enter image description here

The reference variable within method stack frame sets a new value to same object. Therefore, it is reflected when the original ref variable "book" gets its value. Note that in case of passing a reference variable, if it is initialized again in the called method, it then points to a new memory location and any operation does not affect the previous object on the heap.

Therefore, when anything is passed as a method argument, it is always the stack entity, either a primitive or reference variable. We never pass something that is stored on the heap. Hence, in Java, we always pass the value on the stack, and it is passed by value.

1 Comment

The screenshot of code is close to unreadable. It shouldn't not be provided as an image anyway; see for example Why should I not upload images of code/data/errors? (it covers answers as well). Please replace the image with text. Thanks in advance.
4

Here is a more precise definition:

  • Pass/call by value: Formal parameter is like a local variable in scope of function, it evaluates to actual parameter at the moment of function call.
  • Pass/call by reference: Formal parameter is just a alias for the real value, any change of it in the scope of function can have side effects outside in any other part of code.

So in C/C++, you can create a function that swaps two values passed using the references:

void swap(int& a, int& b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

You can see it has a unique reference to a and b, so we do not have a copy; tmp just holds unique references.

The same function in Java does not have side effects. The parameter passing is just like the code above without references.

Although Java works with pointers/references, the parameters are not unique pointers. In each attribution, they are copied instead of just assigned like C/C++.

Comments

3

I think this simple explanation might help you understand as I wanted to understand this same thing when I was struggling through this.

When you pass a primitive data to a function call, its content is being copied to the function's argument and when you pass an object, its reference is being copied to the function's argument. Speaking of object, you can't change the copied reference-the argument variable is referencing to in the calling function.

Consider this simple example, String is an object in Java and when you change the content of a string the reference variable will now point to some new reference as String objects are immutable in Java.

String name="Mehrose";  // Name referencing to 100

ChangeContenet(String name) {
    name = "Michael"; // The reference has changed to 1001

}
System.out.print(name);  // Displays Mehrose

It is fairly simple, because, as I mentioned, you are not allowed to change the copied reference in the calling function. But the problem is with the array when you pass an array of String/Object. Let us see.

String names[] = {"Mehrose", "Michael"};

changeContent(String[] names) {
    names[0] = "Rose";
    names[1] = "Janet"
}

System.out.println(Arrays.toString(names)); // Displays [Rose,Janet]

As we said, we can't change the copied reference in the function call, and we also have seen in the case of a single String object. The reason is names[] variable referencing to let's say 200 and names[0] referencing to 205 and so on. You see, we didn't change the names[] reference; it still points to the old same reference still after the function call but now names[0] and names[1] reference has been changed. We Still stand on our definition that we can't change the reference variable's reference so we didn't.

The same thing happens when you pass a Student object to a method and you are still able to change the Student name or other attributes. The point is we are not changing the actual Student object rather we are changing the contents of it.

You can't do this:

Student student1 = new Student("Mehrose");

changeContent(Student Obj) {
 obj = new Student("Michael") // Invalid
 obj.setName("Michael")  // Valid

}

Comments

3

Consider:

public class Test {

    static class Dog {
        String name;

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Dog other = (Dog) obj;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }

        public String getName() {
            return name;
        }

        public void setName(String nb) {
            this.name = nb;
        }

        Dog(String sd) {
            this.name = sd;
        }
    }
    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        Dog aDog = new Dog("Max");

        // We pass the object to foo
        foo(aDog);
        Dog oldDog = aDog;

        System.out.println(" 1: " + aDog.getName().equals("Max")); // false
        System.out.println(" 2 " + aDog.getName().equals("huahua")); // false
        System.out.println(" 3 " + aDog.getName().equals("moron")); // true
        System.out.println(" 4 " + " " + (aDog == oldDog)); // true

        // part2
        Dog aDog1 = new Dog("Max");

        foo(aDog1, 5);
        Dog oldDog1 = aDog;

        System.out.println(" 5 : " + aDog1.getName().equals("huahua")); // true
        System.out.println(" part2 : " + (aDog1 == oldDog1)); // false

        Dog oldDog2 = foo(aDog1, 5, 6);
        System.out.println(" 6 " + (aDog1 == oldDog2)); // true
        System.out.println(" 7 " + (aDog1 == oldDog)); // false
        System.out.println(" 8 " + (aDog == oldDog2)); // false
    }

    /**
     *
     * @param d
     */
    public static void foo(Dog d) {
        System.out.println(d.getName().equals("Max")); // true

        d.setName("moron");

        d = new Dog("huahua");
        System.out.println(" -:-  " + d.getName().equals("huahua")); // true
    }

    /**
     *
     * @param d
     * @param a
     */
    public static void foo(Dog d, int a) {
        d.getName().equals("Max"); // true

        d.setName("huahua");
    }

    /**
     *
     * @param d
     * @param a
     * @param b
     * @return
     */
    public static Dog foo(Dog d, int a, int b) {
        d.getName().equals("Max"); // true
        d.setName("huahua");
        return d;
    }
}

The sample code to demonstrate the impact of changes to the object at different functions.

Comments

3

Java passes parameters by value. There isn't any option of passing a reference in Java.

But at the compiler binding level layer, it uses reference internally not exposed to the user.

It is essential, as it saves a lot of memory and improves speed.

1 Comment

Every time you pas an object, it is passed by reference, cause that is what you find on the stack: a Reference
2

The Java programming language passes arguments only by value, that is, you cannot change the argument value in the calling method from within the called method.


However, when an object instance is passed as an argument to a method, the value of the argument is not the object itself but a reference to the object. You can change the contents of the object in the called method but not the object reference.


To many people, this looks like pass-by-reference, and behaviorally, it has much in common with pass-by-reference. However, there are two reasons this is inaccurate.

  • Firstly, the ability to change the thing passed into a method only applies to objects, not primitive values.

  • Second, the actual value associated with a variable of object type is the reference to the object, and not the object itself. This is an important distinction in other ways, and if clearly understood, is entirely supporting of the point that the Java programming language passes arguments by value.


The following code example illustrates this point:
1 public class PassTest {
2
3   // Methods to change the current values
4   public static void changeInt(int value) {
5     value = 55;
6  }
7   public static void changeObjectRef(MyDate ref) {
8     ref = new MyDate(1, 1, 2000);
9  }
10   public static void changeObjectAttr(MyDate ref) {
11     ref.setDay(4);
12   }
13
14 public static void main(String args[]) {
15     MyDate date;
16     int val;
17
18     // Assign the int
19     val = 11;
20     // Try to change it
21     changeInt(val);
22     // What is the current value?
23     System.out.println("Int value is: " + val);
24
25 // Assign the date
26     date = new MyDate(22, 7, 1964);
27     // Try to change it
28     changeObjectRef(date);
29     // What is the current value?
30 System.out.println("MyDate: " + date);
31
32 // Now change the day attribute
33     // through the object reference
34     changeObjectAttr(date);
35     // What is the current value?
36 System.out.println("MyDate: " + date);
37   }
38 }

This code outputs the following:
java PassTest
Int value is: 11
MyDate: 22-7-1964
MyDate: 4-7-1964
The MyDate object is not changed by the changeObjectRef method;
however, the changeObjectAttr method changes the day attribute of the
MyDate object.

1 Comment

This is very misleading. You certainly can change the value of an argument from within a method.
2
+150

There are only two versions:

  • You can pass the value i.e. (4,5)
  • You can pass an address i.e. 0xF43A

Java passes primivates as values and objects as addresses. Those who say, "address are values too", do not make a distinction between the two. Those who focus on the effect of the swap functions focus on what happens after the passing is done.

In C++ you can do the following:

Point p = Point(4,5);

This reserves 8 bytes on the stack and stores (4,5) in it.

Point *x = &p;

This reserves 4 bytes on the stack and stores 0xF43A in it.

Point &y = p;

This reserves 4 bytes on the stack and stores 0xF43A in it.

  1. I think everyone will agree that a call to f(p) is a pass-by-value if the definition of f is f(Point p). In this case an additional 8 bytes being reserved and (4,5) being copied into it. When f changes p the the the original is guarantieed to be unchanged when f returns.

  2. I think that everyone will agree that a call to f(p) is a pass-by-reference if the definition of f is f(Point &p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes p the the original is guarantieed to be changed when f returns.

  3. A call to f(&p) is also pass-by-reference if the definition of f is f(Point *p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes *p the the original is guarantieed to be changed when f returns.

  4. A call to f(x) is also pass-by-reference if the definition of f is f(Point *p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes *p the the original is guarantieed to be changed when f returns.

  5. A call to f(y) is also pass-by-reference if the definition of f is f(Point &p). In this case an additional 4 bytes being reserved and 0xF43A being copied into it. When f changes p the the original is guarantieed to be changed when f returns.

Sure what happens after the passing is done differs, but that is only a language construct. In the case of pointer you have to use -> to access the members and in the case of references you have to use .. If you want to swap the values of the original then you can do tmp=a; a=b; b=tmp; in the case of references and tmp=*a; *b=tmp; *a=tmp for pointers. And in Java you would have do: tmp.set(a); a.set(b); b.set(tmp). Focussing on the assignment statement statement is silly. You can do the exact same thing in Java if you write a little bit of code.

So Java passes primivates by values and objects by references. And Java copy values to achieve that, but so does C++.

For completeness:

Point p = new Point(4,5);

This reserves 4 bytes on the stack and stores 0xF43A in it and reserves 8 bytes on the heap and stores (4,5) in it.

If you want to swap the memory locations like so

void swap(int& a, int& b) {
    int *tmp = &a;
    &a = &b;
    &b = tmp;
}

Then you will find that you run into the limitations of your hardware.

2 Comments

One of the most complete answers is bumped to the bottom. Your #3 describes the situation in Java the best.
Not relevant for the semantics: Guess, all Java implementations use two levels of indirection, i.e. a reference is a kind of handle, not yet the object address, which may change by garbage collection.
2

Java uses pass-by-value, but the effects differ whether you are using primitive or a reference type.

When you pass a primitive type as an argument to a method, it's getting a copy of the primitive and any changes inside the block of the method won't change the original variable.

When you pass a reference type as an argument to a method, it's still getting a copy but it's a copy of the reference to the object (in other words, you are getting a copy of the memory address in the heap where the object is located), so any changes in the object inside the block of the method will affect the original object outside the block.

Comments

2

Guess, the common canon is wrong based on inaccurate language

Authors of a programming language do not have the authority to rename established programming concept.

Primitive Java types byte, char, short, int, long float, double are definitely passed by value.

All other types are Objects: Object members and parameters technically are references.

So these "references" are passed "by value", but there occurs no object construction on the stack. Any change of object members (or elements in case of an array) apply to the same original Object; such reference precisely meets the logic of pointer of an instance passed to some function in any C-dialect, where we used to call this passing an object by reference

Especially we do have this thing java.lang.NullPointerException, which makes no sense in a pure by-value-concept

8 Comments

It's still pass-by-value even if the value itself is a reference. The argument is copied and reassigning it doesn't affect anything outside the called function - this is the key difference between pass-by-value/reference.
This seems like the correct answer to me. Why are people so caught up on the technicalities of pass-by-object-reference versus pass-by-reference? If you pass a non-primitive variable to a function, modifications to that variable within the function affect the variable outside of the function. That is pretty much the same behavior as pass-by-reference. "It's still pass-by-value even if the value itself is a reference" - umm, okay, but if the value is a reference then you are passing a reference. Terminology aside, passing objects as arguments can affect the object outside of the function.
@h0r53 Why are people so caught up? Consistent definitions are import for effective communication. What C does, IS ALSO PASS BY VALUE. It's just the java calls its pointers "References". And that's where the confusion comes from. It's a different use of the word reference than in "pass-by-reference". Under the hood a "reference" in java is just a pointer, meaning it's a primitive which holds an address to the object in memory. Yes, you change the object in memory, but not the reference itself. So if you assign a different object or set it to null, the reference outside the function wont change
@h0r53, I can see from your posts (which are great, btw) that you know C and C++. C does not offer Pass by Reference, but C++ actually does by way of allowing "reference parameters". When you declare a function with a header like , void foo(TreeClass& maple), the ampersand makes this a reference parameter (can't do that in C). Now, if you set maple to null inside the function, the change will also be reflected outside the method. Please see my post for details stackoverflow.com/questions/40480/…
@Sanjeev I see your point and the subtle differences in reference v. object-reference are more clear to me. I was admittedly a bit frustrated when writing the prior response because it seemed like the issue was being unnecessarily convoluted with terminology. I just wanted a quick answer - "If I pass an object to a function, and change that object within the function, is it reflected in the caller?" My background causes me to think of everything in terms of pointers, so when I think of pass-by-reference or pass-by-object-reference, I think of pass-by-pointer, which isn't technically correct.
|
1 2
3

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.