Sunday, April 17, 2011

In Java are parameters to methods passed by Value or Passed by reference

Another interesting concept in Java is that whether the parameters to methods are passed by value or passed by reference ?

The correct and sweet answer for this is that everything in Java is passed by value in Java. Period. But it's not as simple as it looks. Let's introspect it further with various possible combinations

Primitives
In Java method invocations, param values are always passed by values, and the same is also demonstrated by the sample code posted below
package com.javainterviewquestion.javaparametercheck;

public class JavaParameterCheck {

public static void main(String args[])
{
JavaParameterCheck javaParamCheck = new JavaParameterCheck();
int a=1;
int b=2;
System.out.println(" Param Values before invoking the method "+a+" and "+b);
javaParamCheck.paramTest(a, b);
System.out.println(" Param Values after invoking the method "+a+" and "+b);
}

public void paramTest(int a, int b)
{
a++;
b++;
}

}

The output of the above sample code is

Param Values before invoking the method 1 and 2
Param Values after invoking the method 1 and 2


Objects

As in Java everything is passed by value , but in case Objects being passed as parameters in the methods the reference of the object is passed by value.Hence any changes done to the object within a method are reflected outside the method too (Only exception being String which is discussed later). E.g. the following code

package com.javainterviewquestion.javaparametercheck;

public class JavaParameterCheck {
public static void main(String args[])
{
JavaParameterCheck javaParamCheck = new JavaParameterCheck();
Employee a = new Employee();
Employee b = new Employee();
b.setName("Second Employee");
System.out.println(" Param Values before invoking the method "+a.getName()+" and "+b.getName());
javaParamCheck.paramTest(a, b);
System.out.println(" Param Values after invoking the method "+a.getName()+" and "+b.getName());
}
public void paramTest(Employee a, Employee b)
{
a.setName("This is first name");
b.setName(" This is second name");
}

}

class Employee
{
String name =" Employee";

public String getName() {
return name;
}

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

has the following output

Param Values before invoking the method Employee and Second Employee
Param Values after invoking the method This is first name and This is second name


The only exception to the Object are String objects, as String are immutable and any changes to the String result in creation of a new String object (pointing to the new memory location). Hence any changes done to the String objects passed as parameters within the method are not reflected outside the method call. E.g. the following code

package com.javainterviewquestion.javaparametercheck;

public class JavaParameterCheck {
public static void main(String args[])
{
JavaParameterCheck javaParamCheck = new JavaParameterCheck();
String a="First String";
String b="Second String";
System.out.println(" Param Values before invoking the method "+a+" and "+b);
javaParamCheck.paramTest(a, b);
System.out.println(" Param Values after invoking the method "+a+" and "+b);
}
public void paramTest(String a, String b)
{
a=a+"1";
b=b+"2";
}

}

has the following output

Param Values before invoking the method First String and Second String
Param Values after invoking the method First String and Second String

Another confusing scenario while passing Objects as parameters to methods is that what will happen if within the method Objects are reinitialized. In that case since the objects are pointing to a new reference , any changes are not reflected outside the method call. See the code below as sample

package com.javainterviewquestion.javaparametercheck;

public class JavaParameterCheck {
public static void main(String args[])
{
JavaParameterCheck javaParamCheck = new JavaParameterCheck();
Employee a = new Employee();
Employee b = new Employee();
b.setName("Second Employee");
System.out.println(" Param Values before invoking the method "+a.getName()+" and "+b.getName());
javaParamCheck.paramTest(a, b);
System.out.println(" Param Values after invoking the method "+a.getName()+" and "+b.getName());
}
public void paramTest(Employee a, Employee b)
{
a = new Employee();
b = new Employee();
a.setName("This is first name");
b.setName(" This is second name");
}

}

class Employee
{
String name =" Employee";

public String getName() {
return name;
}

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

The above code gives the output

Param Values before invoking the method Employee and Second Employee
Param Values after invoking the method Employee and Second Employee

Array Of Primitives/Objects
Since array is also an object in java, any changes done in the method are reflected outside the method for primitives as well as Objects. See the below code as sample.

package com.javainterviewquestion.javaparametercheck;

public class JavaParameterCheck {
public static void main(String args[])
{
JavaParameterCheck javaParamCheck = new JavaParameterCheck();
int[] list = {1,2,3};
Employee[] empList = {new Employee(), new Employee(), new Employee()};
String[] stringList = {"a","b","c"};
System.out.println(" Param Values before invoking the method "+list[0]+" and "+list[1]+" and " + empList[0].getName()+" and "+ empList[1].getName()+"and"+stringList[0]+"and"+stringList[1]);
javaParamCheck.paramTest(list,empList,stringList);
System.out.println(" Param Values after invoking the method "+list[0]+" and "+list[1]+" and " + empList[0].getName()+" and "+ empList[1].getName()+"and"+stringList[0]+"and"+stringList[1]);
}
public void paramTest(int[] intlist, Employee[] empList, String[] stringlist)
{
intlist[0]=9;
intlist[1]=10;
empList[0].setName("First name");
empList[1].setName("Second name");
stringlist[0]="First String";
stringlist[1]="Secong Strings";
}

}

class Employee
{
String name =" Employee";

public String getName() {
return name;
}

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

The output of the above code would be

Param Values before invoking the method 1 and 2 and Employee and Employeeandaandb
Param Values after invoking the method 9 and 10 and First name and Second nameandFirst StringandSecong Strings

Lists
Here also the behavior would be very much similar to that of Arrays as mentioned above.

No comments:

Post a Comment