6

Hi Im studying for my scja exam and have a question about string passing by ref/value and how they are immutable. The following code outputs "abc abcfg".

What I want to know is why is this happening? Im not understanding what happens inside of method f. String is passed by value so surely it should change to "abcde" inside the method? Because if b+="fg" appends to the string why doesnt it work inside the method?

Thanks!

public class Test {

    public static void main(String[] args){
        String a =new String("abc");
        String b = a;
        f(b);
        b+="fg"
        System.out.println(a + " " + b);
    }

    public static void f(String b){
        b+="de";
        b=null;
    }
}
1
  • 1
    The key thing to remember is that references are passed by value. f gets a copy of a reference that is initially a pointer to "fg". Commented Feb 17, 2013 at 0:09

5 Answers 5

8

The line b+="de"; in the void f(String b) functions creates a completely new object of String that does not affect the object in the main function.

So when we say String is immutable when mean any change on a String object will result in creating a completely new String object

public class Test {
    public static void main(String[] args){
        String a =new String("abc");

        String b = a; // both a & b points to the same memory address

        f(b); // has no effect

        // b still has the value of "abc"
        b+="fg" // a new String object that points to different location than "a"

        System.out.println(a + " " + b); // should print "abc abcfg" 
    }

 public static void f(String b){
    b+="de";  // creates a new object that does not affect "b" variable in main
    b=null;
 }
}
Sign up to request clarification or add additional context in comments.

Comments

3

In your method f() you are assigning a new String to the parameter b, but parameters are just like local variables, so assigning something to them has no effect on anything outside the method. That's why the string you passed in is unchanged after the method call.

8 Comments

so I would of had to do b = f(b) and return a string from method f?
Exactly! Even then, until you return the string, there's no effect outside the method.
It's also pointing out that if you were to do b = f(b) and return a String with your current coding, you would be left with the output "abc nullfg", as you say b = null.
I am pretty sure this is very incorrect. String is passed as value, the value is the pointer to the string. When you do anything b+="de"; or null, you effect the pointer. b+="de"; is the same as b = new String; If you do the same, but simply toss the string in a wrapper, and change the data in the wrapper, you will see the changes, as you changed the pointer that the data in the wrapper has, but not the wrapper itself.
@StarWind sure. If you mutate the object, then yes it's the same object being changed as the one assigned to the variable in the calling code, so changes are "seen" outside the method too. It's assignment that does nothing in the calling code.
|
3

This line of code:

b += "de";

Roughly translates to:

b = b + "de";

Which creates a new String and stores it in the local variable 'b'. The reference outside the method is not changed in anyway by this. There are a couple of key things to remember when trying to understand how/why this works this way.

  1. In Java, all method arguments are passed by value.
  2. Methods have a local stack where all their data is stored, including the method arguments.

When you assign a new object to a variable that was passed into a method, you are only replacing the address in the local stack, with the address of the new object created. The actual object address outside of the method remains the same.

Comments

0

When you pass the String into the method, it creates a new String object in the method. If you put a println statement in your method, like this:

public static void f(String b){
    b+="de";
    System.out.println(b);
    b=null;
}

You would see the output "abcde".

However, once you come out of the method, you go back to your original object, which has not been altered. Therefore, appending fg to it will only produce a NEW string (b), containing "abcfg".

Comments

0

Your creating a new object of String when you say something like b+="de"

Its like saying b = new String(b+"de");

If you really want to keep the value passed in then use a stringBuilder like this:

    StringBuilder a =new StringBuilder("abc");
        StringBuilder b = a;
        f(b);
        b.append("fg");
        System.out.println(a + " " + b);
    }

  public static void f(StringBuilder b){
        b.append("de");
        b=null;
    }

Now your output will be "abcdefg" because stringbuilder object b was passed into f as the value of the object itself. I modified the value without using "new" to point to another object. Hope its clear now.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.