Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: setting a reference to null won't affect the object

I've got a simple question. In this code below, why is s3's value still printed although I set it to null before. It seems gargbage collector won't get called.

public class Test {
    public static void main(String[] args) {
         String s1 = "abc", s2 = "def", s3 = "ghj";

         String sarr[] = {s1, s2, s3};
         s3 = null;

         System.gc(); 

         for(int i = 0; i < sarr.length; i++) {
             System.out.print(sarr[i] + " "); //prints abc def ghj
         }
    }
 }

Any thoughts would be appreciated.

like image 769
karakays Avatar asked Nov 28 '11 15:11

karakays


People also ask

Can we assign null to reference in Java?

In Java programming, null can be assigned to any variable of a reference type (that is, a non-primitive type) to indicate that the variable does not refer to any object or array.

Can an object reference be null?

One of the main causes of bugs with null reference is the fact that in C every reference type object can be null, all the time.

What happens when we assign null to object in Java?

If you pass it to a thread to be manipulated, the thread will have a reference to the object until it terminates. In all of these cases, if you set list = null , the references will still be maintained, but they will disappear after these references disappear.

What will happen when you try to access an object reference with a null value?

NullPointerException is thrown when program attempts to use an object reference that has the null value.


2 Answers

When you write:

// Moved [] to make it more idiomatic
String[] sarr = {s1, s2, s3};

That copies the values of s1, s2 and s3 (which are references, not objects) into the array. When the statement has executed, the variables are entirely independent of the array. Changing the value of any of the s1, s2, s3 variables to refer to a different string doesn't affect the contents of the array at all.

It's exactly the same as with other assignments, e.g.

string x = "hello";
string y = x;
x = null; // Doesn't affect y

and method arguments, too.

Note that the garbage collection part is a red herring here - while obviously understanding this is important to understanding garbage collection, the reverse isn't true. The important points are to understand that:

  • The values of s1, s2, and s3 and the elements of the array are references, not objects.
  • The values are copied when creating the array, so changing the variable afterwards doesn't make any difference

Now, to take the example a bit further, consider:

StringBuilder sb = new StringBuilder("Hello");
StringBuilder[] array = { sb };

sb.append(" world");
System.out.println(array[0]);

This will print "Hello world" because here we've only got a single StringBuilder object, which both sb and array[0] refer to. Changing the data inside that object (which isn't the same as changing sb to refer to a different object) makes the change visible however you get at it. This is like me giving the address of my house to two people - if one of them paints my house red, the other person will see that as well.

like image 52
Jon Skeet Avatar answered Oct 10 '22 08:10

Jon Skeet


You've reassigned s3 to point to something else (null), but the reference inside the array is still pointing to the original value ("ghj").

s3 is not a constant pointer to the array location. The value of s3 (the reference to the string value "ghj") was copied into the array. The variable itself is not connected and is free to change to reference another String object independently of what you do with the array contents.

like image 21
Anthony Pegram Avatar answered Oct 10 '22 08:10

Anthony Pegram