DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Enterprise AI Trend Report: Gain insights on ethical AI, MLOps, generative AI, large language models, and much more.

2024 Cloud survey: Share your insights on microservices, containers, K8s, CI/CD, and DevOps (+ enter a $750 raffle!) for our Trend Reports.

PostgreSQL: Learn about the open-source RDBMS' advanced capabilities, core components, common commands and functions, and general DBA tasks.

AI Automation Essentials. Check out the latest Refcard on all things AI automation, including model training, data security, and more.

Related

  • How to Estimate Object Memory Allocation in Java
  • All You Need To Know About Garbage Collection in Java
  • Java Memory Management
  • Heap Memory In Java Applications Performance Testing

Trending

  • Exploring the Frontiers of AI: The Emergence of LLM-4 Architectures
  • Modern Python: Patterns, Features, and Strategies for Writing Efficient Code (Part 1)
  • JUnit, 4, 5, Jupiter, Vintage
  • Securing Cloud Infrastructure: Leveraging Key Management Technologies
  1. DZone
  2. Coding
  3. Languages
  4. Java: What to Know About Passing by Value

Java: What to Know About Passing by Value

Of course, in Java, arguments are always passed by value. Let's see what that means inside and the heap with primitives, collections, and making modifications.

By 
Hussein Terek user avatar
Hussein Terek
·
Updated Nov. 22, 17 · Tutorial
Like (50)
Save
Tweet
Share
62.1K Views

Join the DZone community and get the full member experience.

Join For Free

before describing how arguments are passed in java, it is worth defining how java variables are allocated in memory. basically, we're talking about two types of variables: primitives and objects.

primitive variables are always stored inside the stack memory ( the memory space that holds method-specific variables that are short-lived in addition to references to other objects in the heap ).

however, objects are stored at two stages. the actual object data is stored inside the heap memory ( the memory space that holds objects and jre classes ), and a reference for the object is kept inside stack memory, which just points to the actual object.

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, 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, two 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" by passing several argument types (primitive, wrappers, collections, business objects) and checking whether they are modified after the method call.

passing primitive arguments

public static void main(string[] args) {

    int x = 1;
    int y = 2;
    system.out.print("values of x & y before primitive modification: ");
    system.out.println(" x = " + x + " ; y = " + y );
    modifyprimitivetypes(x,y);
    system.out.print("values of x & y after primitive modification: ");
    system.out.println(" x = " + x + " ; y = " + y );
}


private static void modifyprimitivetypes(int x, int y)
{
    x = 5;
    y = 10;
}


output:

values of x & y before primitive modification:  x = 1 ; y = 2
values of x & y after primitive modification:  x = 1 ; y = 2


output description:

the two variables, x and y , are of primitive types and are thus stored inside the stack memory. when calling modifyprimitivetypes() , two copies are created inside the stack memory (let's say w and z) and are then passed to the method. hence, the original variables are not being sent to the method and any modification inside the method flow is affecting only the copies.

passing wrapper arguments

public static void main(string[] args) {

    integer obj1 = new integer(1);
    integer obj2 = new integer(2);
    system.out.print("values of obj1 & obj2 before wrapper modification: ");
    system.out.println("obj1 = " + obj1.intvalue() + " ; obj2 = " + obj2.intvalue());

    modifywrappers(obj1, obj2);

    system.out.print("values of obj1 & obj2 after wrapper modification: ");
    system.out.println("obj1 = " + obj1.intvalue() + " ; obj2 = " + obj2.intvalue());

}

private static void modifywrappers(integer x, integer y)
{
    x = new integer(5);
    y = new integer(10);
}


output:

values of obj1 & obj2 before wrapper modification: obj1 = 1 ; obj2 = 2
values of obj1 & obj2 after wrapper modification: obj1 = 1 ; obj2 = 2


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 to the reference inside the method is actually changing the reference of the copies and not the original references.

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. they create a new instance each time their state is modified. for more information about immutable classes, check out "how to create an immutable class in java" . string objects work similarly to wrappers, so the above rules apply also on strings.

passing collection arguments

public static void main(string[] args) {
    list<integer> lstnums = new arraylist<integer>();
    lstnums.add(1);
    system.out.println("size of list before list modification = " + lstnums.size());
    modifylist(lstnums);
    system.out.println("size of list after list modification = " + lstnums.size());
}

private static void modifylist(list<integer> lstparam)
{
    lstparam.add(2);
}


output:

size of list before list modification = 1
size of list after list modification = 2


output description:

when defining an arraylist or any collection in java, a reference is created inside the stack that points to multiple objects inside the heap memory. when calling modifylist(), a copy of the reference is created and passed to the method. the actual object data is referenced by two references, and any change done by one reference is reflected in 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.

passing business objects as arguments

public static void main(string[] args) {

    student student = new student();
    system.out.println("value of name before student modification = " + student.getname());
    modifystudent(student);
    system.out.println("value of name after student modification = " + student.getname());
}

private static void modifystudent(student student)
{
    student.setname("alex");
}


output:

value of name before student modification = null
value of name after student modification = alex


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 to the object attributes inside the method are reflected in the original reference.

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 methods affects the original variable:

  1. modifying the value of a primitive argument would never affect the original variable.
  2. changing the reference to 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 an object argument inside a method is reflected outside of it.
  4. modifying collections and maps inside the method is reflected outside of them.

Java (programming language) Object (computer science) Memory (storage engine)

Published at DZone with permission of Hussein Terek, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How to Estimate Object Memory Allocation in Java
  • All You Need To Know About Garbage Collection in Java
  • Java Memory Management
  • Heap Memory In Java Applications Performance Testing

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: