-3

Is java pass by value or pass by reference. My question induced me to write this class so that I may confidently answer. As I was wondering I noticed there might be issue with immutable and mutable object. what I am asking is what is the right answer after looking at the output of this simple class.

class

package notsure.tests;

public class PassingValues {

static Object[] passingValueMethod(int intValue, StringBuilder strValue){
    int recievedIntValue = intValue;
    StringBuilder recievedStrValue = strValue;

    System.out.println("------Let's see mutable objects------");
    System.out.println("----In the called method-------");
    System.out.println("-----New References Without Modification-----");
    //No modification
    System.out.println("Recieved integer: "+recievedIntValue);
    System.out.println("Received StringBuilder: "+ recievedStrValue);
    System.out.println();

    System.out.println("---- New refernces With Modification-----");
    //Modification
    recievedStrValue.append(", I am modified in a method() through a reference ");
    System.out.println("Recieved StringBuilder: "+ recievedStrValue);
    recievedIntValue++;
    System.out.println("Recieved integer: "+recievedIntValue);
    System.out.println();
    //Evaluate the parameter values
    System.out.println("----Received parameter variables current values-----");
    System.out.println("StringBuilder: "+strValue+" \nInteger: "+intValue);
    return new Object[]{recievedIntValue, recievedStrValue};

}
static String passingImmutable(String str){
    String recievedStr = str;
    System.out.println("-----In passpassingImmutable() ------");
    System.out.println("---------without modification------");
    System.out.println("Recieved string with local ref: "+recievedStr);
    System.out.println();
    System.out.println("------With modification-------");
    recievedStr = str+" I am modified";
    System.out.println("Recieved string with local ref: "+recievedStr);
    System.out.println();
    System.out.println("----Let's see the parameter value content---");
    System.out.println("Recieved string with param ref: "+str);
    return recievedStr;
}
public static void main(String[] args) {
    Object[] object = new Object[2];
    int integer = 10;
    StringBuilder stringBuilder=new StringBuilder("Stringbuilder");
    object = passingValueMethod(integer,stringBuilder);
    System.out.println();

    System.out.println("---------Back in Main-------- ");
    System.out.println("----Values returned----");
    for(Object obj:object){
        System.out.println(obj);
    }
    System.out.println();
    System.out.println("----Variables in Main-----");
    System.out.println(integer);
    System.out.println(stringBuilder);
    System.out.println("NOTE: even local Object(except primitive) reference reflect changes");
    System.out.println();
    System.out.println("-----Let's use immutable objects-----");
    String str = "I am a string";
    System.out.println("Value in main before method call: "+str);
    System.out.println();
    passingImmutable(str);
    System.out.println();
    System.out.println("--------------Back in main----------");
    System.out.println("String Value retuned: "+str);
    System.out.println();
    System.out.println("String passed(main reference) value: "+str);

}

}

output

------Let's see mutable objects------
----In the called method-------
-----New References Without Modification-----
Recieved integer: 10
Received StringBuilder: Stringbuilder

---- New refernces With Modification-----
Recieved StringBuilder: Stringbuilder, I am modified in a method() through a reference 
Recieved integer: 11

----Received parameter variables current values-----
StringBuilder: Stringbuilder, I am modified in a method() through a reference  
Integer: 10

---------Back in Main-------- 
----Values returned----
11
Stringbuilder, I am modified in a method() through a reference 

----Variables in Main-----
10
Stringbuilder, I am modified in a method() through a reference 
NOTE: even local Object(except primitive) reference reflect changes

-----Let's use immutable objects-----
Value in main before method call: I am a string

-----In passpassingImmutable() ------
---------without modification------
Recieved string with local ref: I am a string

------With modification-------
Recieved string with local ref: I am a string I am modified

----Let's see the parameter value content---
Recieved string with param ref: I am a string

--------------Back in main----------
String Value retuned: I am a string

String passed(main reference) value: I am a string
LeandreM
  • 943
  • 3
  • 12
  • 24
  • have you googled around for explanations on this? – NG. Sep 23 '13 at 14:13
  • Java is pass by value. Object values are references. – RokL Sep 23 '13 at 14:14
  • 1
    It's not clear why you would "prefer not to be asked" about this - wouldn't it be better just to be confident in the answer? – Jon Skeet Sep 23 '13 at 14:14
  • @Julien believe me I have read that answer multiple times.I still had trouble deciding – LeandreM Sep 23 '13 at 14:15
  • 2
    Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as references and those references are passed by value. (quoted from eldorando) – Philipp Sander Sep 23 '13 at 14:15
  • 1
    @PhilippSander Indeed, I find it amusing that the wrong understanding (that java is pass-by-reference) is far less dangerous than a naive but correct understand (that java is pass-by-value but ignoring that it passes a reference by value) – Richard Tingle Sep 23 '13 at 14:25
  • @RichardTingle that is so true! understanding is the right way to go! not just saying something true – Philipp Sander Sep 23 '13 at 14:28
  • I wouldn't say that `Java passes objects as references` as that is confusing in this context. – RokL Sep 23 '13 at 14:32
  • @PhilippSander I got it. It is pass-by-value. the string is another new object in memory. I got confused about it. but I believed and understood that it is pass-by-value – LeandreM Sep 23 '13 at 14:33
  • With immutable classes (such as strings) the pass by value vs pass by reference is a more hidden, I would experiment with mutable classes (such as Vector3d that I have used in my example). Just to be clear, there is no difference in this respect for mutable vs immutable, its just less clear – Richard Tingle Sep 23 '13 at 14:36
  • @RichardTingle You are right. – LeandreM Sep 23 '13 at 14:37

1 Answers1

2

Java passes a reference by value, this gives it the feel of being pass by reference despite actually being pass by value.

public class Main{

    public static void main(String[] args) {
        Vector3d vectorTest=new Vector3d(1,2,3);
        System.out.println(vectorTest.x); //prints 1
        affectVector(vectorTest);
        System.out.println(vectorTest.x); //prints 100
        replaceVector(vectorTest);
        System.out.println(vectorTest.x); //still prints 100
    }

    public static void affectVector(Vector3d vectorIn){
         vectorIn.x=100; 
    }

    public static void replaceVector(Vector3d vectorIn){
         //this method has no external effect because the reference vectorIn is immediately overrwritten
         vectorIn=new Vector3d(0,0,0); //the reference vectorIn is completely changed
    }


}

You can see that because a reference is passed by value you can still access the object that it refers to but if you replace the reference then you are 'refering' to a different object and that has no effect outside the method.

The analogy I use when trying to describe this is that of postal addresses. A reference is a postal address that you use to send letters (instructions) to objects. You can copy that address onto many pieces of paper but it still sends letters to the same house. It is the postal address that is copied, not the 'house'

Richard Tingle
  • 16,906
  • 5
  • 52
  • 77