Wednesday, December 7, 2022

Is Java Pass by Value or Pass by Reference? Example

Hello guys, Does Java is pass by value or pass by reference is one of the tricky Java questions mostly asked on both beginner and experienced level Java developer interviews. Before debating whether Java is pass by value or pass by reference lets first clear what is pass by value and what is pass by reference actually means?. This question has its origin in C and C++ where you can pass function parameter either value or memory address, where value is stored (pointer). As per Java specification everything in Java is pass by value whether its primitive value or objects and it does make sense because Java doesn't support pointers or pointer arithmetic, Similarly multiple inheritance and operator overloading is also not supported in Java.

This question becomes confusing when the interviewer asks about how an object is passed to a method in Java? The answer to this question is simple whenever a method parameter expects an object, a reference of that object is passed

This reference is like primitives' value which can be copied and two variable holding this reference is still two different variable and if you change the value of one reference variable to point to another object reference, the second variable will not be affected. This is different then changing the object which both these variable points. 

Many programmers confuse reference with pointers here which is not correct, reference is a kind of handle that is used to locate object, or change the object, but it doesn’t allow any pointer arithmetic i.e. you can not increase or decrease memory address and locate a different object using reference in Java.



Pass by Value and Pass by Reference Example in Java

Let’s see two examples of calling method and passing parameter this will clear any doubt whether Java is pass by value or pass by reference. consider following example:


public class PassByValueExample {
 
    public static void main(String args[]) {
       int number = 3;
       printNext(number);
       System.out.println("number Inside main(): "+number);
    }
 
    public static void printNext(int number){
        number++;
        System.out.println("number Inside printNext(): "+number);
    }
 
}

Output:
number Inside printNext(): 4
number Inside main(): 3


Above example clearly shows that primitives are passed as pass by value to method parameters, had Java pass by reference both main method and printNext() would have printed the same value. 

In fact, when you pass the  "number" variable to printNext() method a copy of the value number variable is holding is passed to the printNext() method. So, its actually a copy by value. 




Passing an Object to Java method 

Now look at another example of passing an object as a method parameter which will confuse you that Java is pass by reference, which Java is not. In fact what happens here is a copy of reference is created and passed to method. 

public class PassByReferenceConfusion {
 
    public static void main(String args[]) {
       Car car = new Car("BMW");
       System.out.println("Brand of Car Inside main() before: "+ car.brand);
       printBrand(car);
       System.out.println("Brand of Car Inside main()after: "+ car.brand);
    }
 
    public static void printBrand(Car car){
        car.brand = "Maruti";
        System.out.println("Brand of Car Inside printBrand(): "+car.brand);
    }
 
    private static class Car{
        private String brand;
     
        public Car(String brand){
            this.brand = brand;
        }

    }
}

Output:
Brand of Car Inside main() before: BMW
Brand of Car Inside printBrand(): Maruti
Brand of Car Inside main()after: Maruti


If you see the change made in the method parameter is reflected globally i.e. brand of car is changed in all places it means one object is used in both methods. Well in reality if you pass an object as a method parameter in Java it passes "
value of reference" or in simple term object reference or handles to Object in Java

Here reference term is entirely different than reference term used in C and C+ which directly points to a memory address of variable and subject to pointer arithmetic. in Java object can only be accessed by its reference as you can not get a memory address where the object is stored or more precisely there is no method to get the value of an object by passing memory address.

To prove the point that reference variable is passed by value, I will show you another example:

public class PassByCopyOfReference {
 
    public static void main(String args[]) {
       Car car = new Car("BMW");
       System.out.println("Brand of Car Inside main() before passsing: "+ car.brand);
       printBrand(car);
       System.out.println("Brand of Car Inside main()after: "+ car.brand);
    }
 
    public static void printBrand(Car newCar){
        newCar=  new Car("Tesla");
        System.out.println("Brand of Car Inside printBrand(): "+ newCar.brand);
    }
 
    private static class Car{
        private String brand;
     
        public Car(String brand){
            this.brand = brand;
        }

    }
}

Output:
Brand of Car Inside main() before: BMW
Brand of Car Inside printBrand(): Tesla
Brand of Car Inside main()after: BMW


You can see that the value of "car" variable after calling the method in main() is printed as "BMW" and not "Tesla" because we didn't change the object pointed by "car" variable in main(), instead we changed the "newCar" variable to point to new object which is Tesla. 

This proves that when you pass the object, only its reference is copied and passed to method parameter. This happens when you call printBrand() method, both "car" and "newCar" points to a Car object which is "BMW" but later "newCar" points to a "Tesla" but "car" still points to "BMW" because they are two separate copies. 

It's said that a picture is worth a thousand word, let's if the below picture can help you to understand this concept better. You can clearly see that initially both "car" and "newCar" pointing to same object but when we created new object and assigned that to newCar variable both are pointing to difference object because a copy of reference of "BMW" object was passed rather than actual object. 

Is Java Pass by Value or Pass by Reference? Example




Does Java passes parameter by value or pass by referenceThat's all about whether Java is pass by value or pass by reference. To conclude everything in Java including primitive and objects is pass by value, I mean "Java is always pass by value". In case of object value of the copy of  reference is passed. Every time you pass a primitive or object a copy of value is passed whether its actual primitive value which reside in stack or an object reference which points to the actual object in the heap. From the code example I shared above, we have also proved this point for once and all. 


Other Java Interview articles you may like

16 comments:

  1. A slightly modified version (picked up from stack over flow). Assigning a new object in called method may make it clear how it would not affect object in calling method.

    public static void main(String args[]) {
    Car car1 = new Car("BMW");
    System.out.println("Brand of Car Inside main() before: " + car1.brand);
    printBrand(car1);
    System.out.println("Brand of Car Inside main() after printBrand: " + car1.brand);
    printBrandAgaian(car1);
    System.out.println("Brand of Car Inside main() after printBrandAgain: " + car1.brand);
    }

    public static void printBrand(Car car2) {
    car2.brand = "Maruti";
    System.out.println("Brand of Car Inside printBrand(): " + car2.brand);
    }

    public static void printBrandAgaian(Car car3) {
    car3 = new Car("Mercdes");
    System.out.println("Brand of Car Inside printBrandAgain(): " + car3.brand);
    }

    ReplyDelete
  2. I knew that Java does not support pass by reference simply because lack of pointers in Java but object reference always seems confusing to me because it looks exactly similar to pass by reference. Thanks for clear wording which helps to isolate this single case in Java. By the this is also referred as call by value and call by reference :)

    ReplyDelete
  3. Whether or not there is "value copy" depends on the compiler. And yes, Java holds all "copies" of a reference as actual parameters when it is passed to methods.

    The real "pass-by-reference" then should replace formal parameters by what is passed in to let everything in the "passing chain" share the same reference.

    ReplyDelete
  4. If Java is Passing reference of the value, how do things happen across JVMs. or say objects passed in EJBs

    ReplyDelete
  5. I hate this "debate". It's simple. The bit pattern of the value is copied into the parameter. It doesn't matter if it's a primitive or a reference type. There's no need to cloud the issue with pseudo-terms like pass-by-value. If the bit pattern is a primitive, or if the bit pattern is a reference to an object, its bits are simply copied. It's easy to understand, and no special terms are needed to explain it.

    (Pass-by-value, -reference, are anachronisms for most programmers. Fortran, C, Pascal and other old-school languages had syntax for that supported different ways of passing parameters, but in almost all modern languages it's just pass-by-value.)

    ReplyDelete
  6. Oops! I meant "pseudo-terms like pass-by-reference". It's ALL pass-by-value.

    And in response to Anonymous June 7 regarding JVMs and EJBs -- that's why objects need to be serialized in some environments. Across VMs, the object is serialized and re-created on the other machine. There's no call stack, and it's really a whole other topic.

    ReplyDelete
  7. How it stands true in case of array as a method parameters?

    ex:-

    int arr[]=new int [4];

    printArray(arr);

    public static void printArray( int [] temp)
    {
    sysout...
    }

    ReplyDelete
  8. public class PassByValue1 {
    public static void main(String[] args) {
    Integer len = 10;
    System.out.println("len = " + len);
    m1(len);
    System.out.println("len = " + len);
    }

    public static void m1(Integer Length) {
    Integer len = 15;
    Length = len;
    }
    }

    ReplyDelete
  9. Thnks sir, ur blog is a treausre.
    But one thing i wanto point out that: there are actually three ways in c++: Pass by value,pass by pointer, pass by reference. In c there are only two: pass by value and pass by pointer.
    This is explained in book: Programming inC++ by Anshuman Sharma.

    ReplyDelete
  10. Hi,

    The brand field in Car class is private, how can you do car.brand = "Maruti"; ? Does your program compile?

    In PassByReferenceConfusion example, you passed the reference to car object to method printBrand and this method changed the state of the car object, that's why the main method see this change which mean you passed the reference to the object itself! This is a typical example of method that introduces a side effect (the change of the car object) and that's why immutable objects are a best practise in java, to avoid this kind of side effects.

    cheers

    ReplyDelete
  11. The article is completely wrong. This is probably the most persistent java myth!

    Objects are ALWAYS PASSED BY REFERENCE! It's completely irrelevant that you get a copy of the reference, you won't get a copy of the object! That's the key point! Using that "copy of the reference" you can modify the original object! That's actually why people use pass-by-reference, so that there's no duplicate of that object and all the implications of it. No one cares about swapping or who knows what other IRRELEVANT thing.

    ReplyDelete
  12. Why Pass by reference is not applicable for Wrapper classes even though we create object for these classes?

    ReplyDelete
  13. Ok when you say: reference stores only "handle".. what exactly is this "handle".. how do we view it.. its a "address" or its just another "variable"...? what do we see it in memory.

    ReplyDelete
  14. @Anonymous, it's basically something (a data structure) which allow you to modify, view or access and object. Yes, it does contain the memory address of object. Please see JVM internals specification to learn more about how reference variable works in Java.

    ReplyDelete
  15. Java references are pointers and as with primitives are passed by value. End of story. The fact you can not perform pointer arithmetic is neither here nor there.

    ReplyDelete
  16. This is one of the most false ideas about how java works. Pass-by-value always means that the method operates on DUPLICATED DATA, which is then returned by a return function. Pass-by-reference always works via a reference(pointer like) and operates on the original data - which is how java objects work. The fact that original variables can't be made to point to something else, is totally irrelevant to the issues, as is the fact that value of the reference is being(how else could that be achieved)

    ReplyDelete