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.
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.
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.
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.
NullPointerException is thrown when program attempts to use an object reference that has the null value.
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:
s1
, s2
, and s3
and the elements of the array are references, not objects.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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With