Java is pass by Value or pass by Reference

This was one of most difficult topic to explain during trainings and discussions. reason is “Humans are always see things through what they knows” As you may already know every human think in their mother (most fluent) language and translated when they speak different language. that because for brain it is very much easy to process through what already know. what happen here is most of developers first learn C and C++. there they lean pointers , by value , by reference and all. after that when they hear “Reference” or “Value” they trying to understand that through what they already knows. as a result they mis inter print the concepts.

I want to point one thing before start this. if you want to explain water flow of river, don’t go in to river. come out from river and look in to that, stand on ground and look at river. so you can give better explanation as well as you can get better idea how water flow in river. if you trying to explain that while you middle of river your explanation would be wrong because you are tying to explain and understand what you feel.

I have heard enough this term in interviews. “Java is pass by value for primitive and pass by reference for object” this is totally wrong understanding. its mis understand due to the reason which I have explained above.

Java is not passing by reference at all. Java always pass by value.

lets dig in to the topic

confusion on this issue because different people have their definitions of the term “reference”. developers who leant C first, think reference is a pointer. who learnt C++ think all “reference”in the world is same as what is reference in C++ people who started with visual basic this is more worst. so your answer depends on what you understand as reference. other wise you can say “yes yes.. that is what i said 🙂 ”

What is by value?

By value mean program evaluate the actual variable and take a copy of result in to method call. so what you do inside invoked method does not effect to original value

What is by Reference

When it by reference new parameter would be just other name for original parameter. what ever changes you do on new parameter is effecting to original value

So then?

as Java specification state how its method invocation works java always work as by value. but it use references. and it passed references but those references are passed by value. as i explain above “how to explain river” new people who getting in to java get confused on this “reference” they interpret this as pass by reference.

lets discuss this with few examples.

Rules and warning

it is highly recommended to go through all example given. other wise you will ended up for wrong conclusions. these example are design a way you to understand concept step by step

objects are passing by reference?

this is the most hate thing to hear. this is a myth. i have heard some java trainers are also teaching this way. lets see

package com.krishantha.sample.java;

public class Application {

	public static void main(String[] args) {

		int x = 10;
		int y = 20;
		System.out.println("X is : " + x + " and Y is : " + y);
		swap(x, y);
		System.out.println("X is : " + x + " and Y is : " + y);

	}

	public static void swap(int a, int b) {
		int c = a;
		a = b;
		b = c;
		System.out.println("A is : " + a + " and B is : " + b);
	}
}

output is

X is : 10 and Y is : 20
A is : 20 and B is : 10
X is : 10 and Y is : 20

why is that ? simply because primitive type pass by value. so original value does not get effected. how this work with object?

package com.krishantha.sample.java;

public class Application {

	public static void main(String[] args) {

		Integer x = new Integer(10);
		Integer y = new Integer(20);
		System.out.println("X is : " + x + " and Y is : " + y);
		swap(x, y);
		System.out.println("X is : " + x + " and Y is : " + y);

	}

	public static void swap(Integer a, Integer b) {
		Integer c = a;
		a = b;
		b = c;
		System.out.println("A is : " + a + " and B is : " + b);
	}
}

output would be

X is : 10 and Y is : 20
A is : 20 and B is : 10
X is : 10 and Y is : 20

you can see nothing changed. that means does not matter primitive or object its teated in same way. then why this confusion. lets go in to little advance example

carefully refer below code.

package com.krishantha.sample.java;
 
public class Application {
 
    public static void main(String[] args) {
 
        Student student;
        Course course;
        int id;
 
        student = new Student();
        course = new Course("Java");
        id = 10;
 
        student.setCourse(course);
        student.setId(id);
 
        System.out.println("before " + student);
        changeStudent(student);
        System.out.println("after " + student);
 
    }
 
    private static void changeStudent(Student student2) {
 
        Student newStudent = new Student();
        Course newCourse = new Course("spring");
        newStudent.setId(20);
        newStudent.setCourse(newCourse);
        student2 = newStudent;
 
    }
}

in this code in changeStudent method it assign its parameter to new student and new class. since student2 assigned to new student at the last line original student (java and id 10) should change to (spring and id 20). but see the output

before Java-10
after Java-10

Nothing changed. how that comes? lets see with few diagrams

Student student;
Course course;
int id;

with above line it just create variable but pointed to no where. means null

img1

below code with create object and point to those objects. for easy of understand asume student object create on memory #100 and course object create on #200

student = new Student();
course = new Course("Java");
id = 10;

we can draw that in this way

img2

now we add course to student. what really do here is create reference to course (memory address #200) from student object. you can prove this your self if you change this course object value after assign to student that does effect to the value which originally assigned.

student.setCourse(course);
student.setId(id);

img3

now if you considered about changeStudent method it need parameter in form of student. so now in memory we have variable created as student2 but pointed to no where. means null

private static void changeStudent(Student student2)

img4

but when call this method we pass student object over there (not really true. but think as for this movement). so we can draw that in this way

changeStudent(student);

img5

inside method we create new objects with below code. we can assume newStudent create on memory address #300 and newCourse at #400

Student newStudent = new Student();
Course newCourse = new Course("spring");
newStudent.setId(20);
newStudent.setCourse(newCourse);

img6

next part is the most confusable part.

student2 = newStudent;

here most of developers get confused. since student passed to student2 parameter and newly created newStudent assigned to student2 they think memory address #300 should go and replace #100. but this how that works

img7

student2 reference point removed from memory address #100 and pointed to #300. therefore when you return from the method memory address #100 (student) is remaining unchanged. if this is pass-by-reference values of #200 should copy in to #100

Deep and deeper

since now you are in track lets consider more confusing example. developers who argue java as reference type take this type of example to prove their concept. in previous example method did not changed original object. but if you consider this example it does change value of the object inside method. so this is not pass by reference?

package com.krishantha.sample.java;

public class Application {

	public static void main(String[] args) {

		Student student;
		Course course;
		int id;

		student = new Student();
		course = new Course("Java");
		id = 10;

		student.setCourse(course);
		student.setId(id);

		System.out.println("before " + student);
		changeCourse(student);

		System.out.println("after " + student);

	}

	private static void changeCourse(Student student1) {

		Course course2 = new Course("Angular");
		student1.setCourse(course2);

	}

}

output will come as bellow.

before Java-10
after Angular-10

when first look its seems like this is by reference. lets draw this to understand what is happening here.

first set of code up to method call is same as previous example. so no need to draw it again. from method initially its create variable call student1 but point to nothing (null)

img8

when we call this method this is reference to student object which is in #100

changeCourse(student);

img9

inside that method we create new object (assume memory address #600)

Course course2 = new Course("Angular");

img10

this is the tricky point here

student1.setCourse(course2);

this is how its work

img11

you can clearly see here object which is in #100 is had reference to #200. with above code line it changed from #200 to #600 however nothing changed on #100. its remain untouched and unchanged. in other term value of #100 is still same.

what here need to understand is student or student1 or student2 or newStudent are are not Student. those are pointers. student or student1 or student2 or new Student does not hold any value. values is in #100 or #300. what they do is just pointing to value based on instructions.

School from nursery.

now nursery is over. 🙂 time to go school. means to time to understands how exactly java works on this. this make you little confuse as this is may against what you already know. but stay calm and read multiple time. so you will understand.

First.. said that primitive are by value and object are by reference is totally lie.

second.. even I have used “pointer” term on above, in reality no pointers in java. java does not deal with pointers as C does. then how its works?

java not passing object in to a method. also its not passing reference. what it does is pass copy of reference value to method. (hope you start to get confused 🙂 ) its like this.

variable name is just an alias for memory address. those are created on stack and hold information how it can refer objects from heap. JVM can determine how get reference to heap object by reading this information. it could be some value like 0x3fda45 when you pass object to method (that is how you see) what java does is it pass  those instructions (0x3fda45) in other words value of the variable or value of the reference to method. as said before it contains instruction to get object from heap. in simple term now you know java not passing object or reference. what it pass is value of the memory location. (since memory location hold reference information we can say value of reference)

Also take note when you pass student to changeCourse method student1 and student both pointed to same object (refer diagram) because it passed value of the reference student variable to method means assign to student1.  student1 assigned with same instruction set means JVM perspective student and student1 hold same instructions. so when JVM trying to pick object from heap based on instruction which hold by variable same object will come as both are hold same instructions.

changeCourse(student);

passing this value to method does not modify original. that means we take copy of that instruction (0x3fda45) and pass. if you go top of the article it says by value mean “evaluate the actual variable and take a copy of result in to method call” that is exactly what happen. means java is ONLY and ONLY pass by value 🙂 🙂

 

Share this on your world...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin
Email this to someone
email
Print this page
Print

One Response to “Java is pass by Value or pass by Reference”

  1. How Java choose most specific method to call A.K.A avoid is ambiguous for the type Other Error | [NOK] - Notes of Krish

    […] we are passing value as null. basically null can be assign to to any reference type variable. ( if you don’t understand this concept refer this article) when you pass null there are two methods eligible to call. as we discussed java considered number […]

    Reply

Leave a Reply