Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Passing Objects To Functions - Call BY Value Or Reference

 
ch praveen
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Friends,
I want to know whether java implements call by value or reference when we pass objects to a function. For me it gave controversial results. i.e for objects such as Integer, approach is call by value and for user defined objects and some objects such as Hashtable, approach is call by reference. If we return a object from a class and if we make any changes to it, they are reflected in the class which returned that object even if access specifier of that object is private. Kindly suggest me which objects are call-by-value by default and which are call-by-reference by default and what we must do inorder pass a object as a reference or as a value as per the situation. Programs which could reveal the scenario in precise are represented below.
--------------------
class Level3 {
public Level3() { }
public void method1(Level1 level1) {
level1.a = 500;
level1.b = 500;
}
}
class Level2 {
private Level1 level1;
Level3 level3;

public Level2(Level1 level1) {
this.level1 = level1;
level3 = new Level3();
}
public void method1() {
level1.a = 200;
level1.b = 200;
}
public void method2() {
level1.method1();
}

public void method3() {
level3.method1(level1);
}
public Level1 getLevel1() {
return level1;
}
public void printLevel1Values() {
level1.printValues();
}
}

class Level1 {
int a;
int b;
public Level1() {
a = 100;
b = 100;
}
public void printValues() {
System.out.println("a = " + a + ", b = " + b);
}
public void method1() {
System.out.println("This Is method1() in Level1 Object");
}
}
public class Class_Sharing1 {
public static void main(String args[]) {
Level1 level1 = new Level1();
Level2 level2 = new Level2(level1);
System.out.println("Before level2.method1()");
level1.printValues();
level2.method1();
System.out.println("After level2.method1()");
level1.printValues();
System.out.println("Calling level2.method2()");
level2.method2();
level2.method3();
System.out.println("After level2.method3() which internally calls level3(level1)");
level1.printValues();
Level1 obj = level2.getLevel1();
obj.a = 800;
obj.b = 800;
System.out.println("After calling level2.getLevel1() and doing some modifications, calling level2.printLevel1Values()");
level2.printLevel1Values();
}
}
OUTPUT ::
---------
D:\jdk1.3\bin>java Class_Sharing1
Before level2.method1()
a = 100, b = 100
After level2.method1()
a = 200, b = 200
Calling level2.method2()
This Is method1() in Level1 Object
After level2.method3() which internally calls level3(level1)
a = 500, b = 500
After calling level2.getLevel1() and doing some modifications, calling level2.printLevel1Values()
a = 800, b = 800
-----------------
import java.util.Hashtable;
class SubClass1 {
private Hashtable ht= new Hashtable();
public SubClass1()
{
ht.put("1","This value is set in Subclass1's constructor (original value)");
}
public void processInteger(Integer ival) {
ival = new Integer(5);
}
public void processHashtable(Hashtable hval) {
hval.put("1","This is new value");
}
public Hashtable getHashtable() {
return ht;
}
public void printHashtable() {
System.out.println("Hasttable,ht value in Subclass1 is " + ht);
}
}
class SubClass2 {
public SubClass2() { }
public void process(SubClass1 sc1) {
Hashtable temptable = new Hashtable();
temptable = sc1.getHashtable();
temptable.put("1","This is the value set in SubClass2 Object's process() method (modified value)");
}
}
public class Class_Vars_Funcs {
static Integer ivar = new Integer(1);
static Hashtable static_ht = new Hashtable();
public static void main(String args[]) {
SubClass1 sc1 = new SubClass1();
SubClass2 sc2 = new SubClass2();

static_ht.put("1","This is original value");
System.out.println("Before calling method-->processInteger(), ivar(static Integer) = " + ivar.intValue());
sc1.processInteger(ivar);
System.out.println("After calling method-->processInteger(), ivar(static Integer) = " + ivar.intValue());
System.out.println("Before calling method-->processHashtable(), static_ht(static Hashtable) = " + static_ht);
sc1.processHashtable(static_ht);
System.out.println("After calling method-->processHashtable(), static_ht(static Hashtable) = " + static_ht);
System.out.println("Before calling method-->sc2.process(sc1)");
sc1.printHashtable();
sc2.process(sc1);
System.out.println("After calling method-->sc2.process(sc1)");
sc1.printHashtable();
}
}
OUTPUT ::
---------
D:\jdk1.3\bin>java Class_Vars_Funcs
Before calling method-->processInteger(), ivar(static Integer) = 1
After calling method-->processInteger(), ivar(static Integer) = 1
Before calling method-->processHashtable(), static_ht(static Hashtable) = {1=This is original value}
After calling method-->processHashtable(), static_ht(static Hashtable) = {1=This is new value}
Before calling method-->sc2.process(sc1)
Hasttable,ht value in Subclass1 is {1=This value is set in Subclass1's constructor (original value)}
After calling method-->sc2.process(sc1)
Hasttable,ht value in Subclass1 is {1=This is the value set in SubClass2 Object's process() method (modified value)}
---------------
Regards,
Ch.Praveen
 
Greg Reinl
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's a good explanation of this right here at the "ranch": Pass-by-value.
 
Eddie Vanda
Ranch Hand
Posts: 283
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What's confusing is that the wrapper classes (Integer, Long, etc) do not have any setter methods. They are passes by reference, but the reference is really a value you can change to point to a new wrapper class that will not be seen by the caller.
 
Tha'er Zayed
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
within the same JVM:
objects get passed around by reference
primitives get passed by value
across different JVMs
objects are passed by value
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Or with other words: in Java there is no way to pass objects to functions. The only thing you can pass to functions are primitive values and references. Both are passed by value.
Of course when you pass a reference to an object by value, it's quite similar to passing the object itself by reference...
 
fred rosenberger
lowercase baba
Bartender
Posts: 12122
30
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I understand it, EVERYTHING in Java is pass by value. There are no exceptions.
HOWEVER... while we often say that we "pass an object", we're really not. when i say

myFoo is NOT - repeat - NOT an object. myFoo is a REFERENCE to an object. It is similar to a C/C++ pointer. So when you pass myFoo into a method, you pass a COPY, or the VALUE, of the reference.
What implication does this have? well, you now have two things pointing to the same object. if the inner one calls a method that modifes the object (like a setter method), the change will be there when you get back to your calling method. but if you CHANGE what the inner one points to, then no further changes will be seen outside the method... for example...

note - i think this code is right - it's early, and i've had no coffee
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic