简体   繁体   中英

Confused about memory in java

From my understand objects in java are passed by reference, or to be more exact, the references to objects are passed by value. So, if I declare a string and pass it into a function where I change the value of the string, why doesn't the original string change? For example:

class Thing 
{

    static void func(String x){ x = "new"; }

    public static void main(String [] args)
    {
        String y = "old";
        func(y);
        System.out.print(y);
    }
}

Why is the value of y still "old"?

EDIT: Why does the following set the attribute x of Thing something to 90?

class Thing { int x = 0; 

static void func(Thing t){ t.x = 90; }

public static void main(String [] args){
    Thing something = null;
    something = new Thing();
    func(something);
    System.out.print(something.x);
}
}

First of all everything in java is pass by value. Even references are also pass by value.

You have created a new string literal and not returning that in the method func() .

You are modifying the passed argument not the original string , hence you can't see the changes.

You might need this,

public static void main(String [] args)
    {
        String y = "old";
        y= func(y);
        System.out.print(y);
    }

 static String func(String x){ 
  x = "new";  
  return x
 } 

Edit for the comment:

No they both are not Identical. There a lot of difference between two ways of String , especially in the memory aspect.

Read

Edit2:

In first case you are created a new string literal in the func method, but here you are modifying the reference.

Your doubt clarifies when you done

  static void func(Thing t){
     t = new Thing(); //as like previous example
     t.x = 90;       // points to new one. Not the original.

    }

Now check the result.

As stated here :

Java passes everything by value, and not by reference – make sure you remember that. And when we say everything, we mean everything – objects, arrays (which are objects in Java), primitive types (like ints and floats), etc. – these are all passed by value in Java. What is the difference between pass by value and pass by reference? When passing an argument (or even multiple arguments) to a method, Java will create a copy or copies of the values inside the original variable(s) and pass that to the method as arguments – and that is why it is called pass by value. The key with pass by value is that the method will not receive the actual variable that is being passed – but just a copy of the value being stored inside the variable.

It has nothing to do with immutability. It's all about how parameters are passed and the scope of variables.

Here is your function call

String y = "old"; // The reference y pointing to the string object "old": y ---> "old"
func(y);  

and when you enter the called function

static void func(String x){  // x = y which means x now points to "old": x ---> "old"
    x = "new"; // x ---> "new": now the local variable x is pointing to a different object. y still points to "old".
} //Scope of x ends here

When we print it

System.out.println(y);

y still points to "old". A new String object was assigned to x which was local to the method func. Therefore, it still prints "old".

So, if I declare a string and pass it into a function where I change the value of the string, why doesn't the original string change?

The important thing to know is that you cannot declare a variable whose value is a string -- strings (which are objects) are not values in Java. y is a reference (a pointer to an object). The only types in Java are primitive types and reference types. The type String is a reference type .

Hence, you are passing y , a reference (a pointer to an object). Inside the function, x is likewise a reference (a pointer to an object). Changing the value of a reference (eg assigning ( = ) to x ) never has any effect on the object it may have pointed to.

The . operator allows you to access a field of the object pointed to by a reference. Assigning to the result of a . access changes the object pointed to by the reference, not the reference itself. These are very different things.

In Java Objects and Strings are treated differently, Strings are kept immutable in JAVA.

To be more clear in your example:

Lets assume, String y is pointing to memory location 2000 and string x is pointing to memory location 2001, so you get the same old value..

In case of objects please refer my example:

http://javaambition.blogspot.kr/2013/08/java-pass-by-value.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM