Java – pass by reference or pass by value

Before describing how arguments are passed in java, it is worth to define how java variables are allocated inside the memory. Basically we talk about 2 types of variables: primitives and objects.

Primitive variables are always stored inside the stack memory (the memory space which holds method specific variables that are short-lived, in addition to references to other objects in the heap) ,  however in case of objects, they are stored at 2 stages, the actual object data is stored inside the heap memory (the memory space which holds objects and JRE classes) and a reference for the object is kept inside stack memory which just points to the actual object.

by value VS by reference

1. By value VS By reference

What is meant by “By value” and “By reference”:

  • By value: when arguments are passed by value to a method, it means that a copy of the original variable is being sent to the method and not the original one, so any changes applied inside the method are actually affecting the copy version.
  • By reference: When arguments are passed by reference, it means that a reference or a pointer to the original variable is being passed to the method and not the original variable data.

2. How arguments are passed in java?

In java, arguments are always passed by value regardless of the original variable type. Each time a method is invoked, the following happens:

  • A copy for each argument is created in the stack memory and the copy version is passed to the method.
    • If the original variable type is primitive, then simply, a copy of the variable is created inside the stack memory and then passed to the method.
    • If the original type is not primitive, then a new reference or pointer is created inside the stack memory which points to the actual object data and the new reference is then passed to the method, (at this stage, 2 references are pointing to the same object data).

3. Fixing some concerns !!

In the following example, we try to validate that “java is always pass by value” through passing several argument types (primitive, wrappers, collections, business objects) and checking whether they are modified after the method call.

  • Passing primitive arguments:  

    Output:

    Output Description:

    The 2 variables x & y are of primitive types and they are stored inside the stack memory. When calling modifyPrimitiveTypes(), 2 copies are created inside the stack memory (let’s say w & z) and then passed to the method. Hence original variables are not being sent to the method and any modification inside the method flow is affecting only the copies.

    pass primitive arguments java

 

 

 

 

 

 

 

  • Passing wrapper arguments:

    Output:

    Output Description:

    Wrappers are stored inside the heap memory with a correspondent reference inside the stack memory.

    When calling modifyWrappers(), a copy for each reference is created inside the stack memory and the copies are passed to the method. Any change on the reference inside the method is actually changing the reference of the copies and not the original references.

Pass wrapper arguments java

P.S: if you change the value of wrapper objects inside the method like this: x += 2, the change is not reflected outside the method since wrapper objects are immutable which means that they create a new instance each time their state is modified. For more information about immutable classes check “How to create an immutable class in java”. String objects work similar to wrappers, so the above rules apply also on strings.

  • Passing Collection argument:

    Output:

    Output Description:

    When defining an Arraylist or any collection in java, a reference is created inside the stack which points to multiple objects inside the heap memory, when calling modifyList(), a copy of the reference is created and passed to the method, so that the actual object data is referenced by 2 references and any change done by one reference is reflected on the other.

    Inside the method, we called lstParam.add(2) , which actually tries to create a new Integer object in the heap memory and link it to the existing list of objects . Hence the original list reference can see the modification since both references are pointing to the same object in memory.

    pass collection arguments java

  • Passing business object as argument:

    Output:

    Output Description:

    The student object is created inside the heap space and a reference for it is defined inside the stack, when calling modifyStudent(), a copy of the reference is created inside the stack and passed to the method. Any modifications on the object attributes inside the method is reflected on the original reference.

    Pass object argument java

4. Conclusion

In java, arguments are always passed by value , the copy would be either a reference or a variable depending on the original variable type. From now on, you can use the following tips in order to understand how modifying arguments inside the method affect the original variable:

  1. Modifying the value of a primitive argument would never affect the original variable.
  2. Changing the reference of an object argument inside the method would never affect the original reference, however it creates a completely new object in the heap space.
  3. Modifying the attributes of the object argument inside the method is reflected outside it.
  4. Modifying collections & maps inside the method is reflected outside it.

 

husseinterek

Founder of programmergate.com, I have a passion in software engineering and everything related to java environment.

You may also like...

16
Leave a Reply

avatar
12 Comment threads
4 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
13 Comment authors
mirzaNeelesh PantMrityunjaypurna kaparouthuRajat Recent comment authors
newest oldest most voted
vikas
Guest
vikas

great explanation

Ritika
Guest
Ritika

Nice explanation

Sudheer
Guest
Sudheer

Great work, clean and nice explanation..

Turkmen
Guest
Turkmen

One of the greatest explanations of this topic I have ever came across ! thanks

Sunil
Guest
Sunil

This is very clear explanation. Good work. Please keep doing the same.

Pramithas Dhakal
Guest
Pramithas Dhakal

In “Passing wrappers as arguments”, both ref1 and ref3 are pointing to the same object, obj1. So, why do the change in ref3 does not change the contents pointed by ref1 since they both point to the same object. And why is it different from passing business object and collection as arguments?

Arpit Agrawal
Guest
Arpit Agrawal

Nice Explanation

Rajat
Guest
Rajat

excellent 🙂

purna kaparouthu
Guest
purna kaparouthu

awesome

Mrityunjay
Guest
Mrityunjay

very Nice Explanation, Great work….keep it up.

Neelesh Pant
Guest
Neelesh Pant

One of the best Article i have read so far on Pass by Value VS Pass by reference

mirza
Guest
mirza

i just love your frontend design of this webpage