Olivier J.
Olivier J.

Reputation: 3165

Java and references

I have basic class :

 public class SomeClass {

    private List<String> list = new ArrayList<String>();

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }   

}

In a method I have this code :

private void test(){

    SomeClass sc1 = new SomeClass();
    sc1.getList().add("a");
    sc1.getList().add("b");

    SomeClass sc2 = sc1;

    System.out.println(sc2.getList().size());

    sc1.getList().remove(0);
    System.out.println(sc2.getList().size());

    sc1=null;
    System.out.println(sc2.getList().size());

    sc2=null;
    System.out.println(sc2.getList().size());


}

I receive :

but I though I would received :

If a referenced object is set to null, the reference link is broken ? Thank you for clarifications

Upvotes: 0

Views: 118

Answers (4)

Jon Skeet
Jon Skeet

Reputation: 1500235

If a referenced object is set to null, the reference link is broken ?

There's no such concept as setting an object to null, You can only set a variable to null. This statement:

sc1=null;

... changes the value of sc1 and that is all.

A variable is simple a storage location with a name. The storage location has a value, and for variables whose type is non-primitive, that value is a reference. It's very important to understand that the value of the variable is not an object. It's just a reference.

So this statement:

SomeClass sc2 = sc1;

just declares a new variable (sc2) which starts off with the same value as an existing variable (sc1). The two variables are completely separate - they just happen to have the same value to start with.

I like to think of variables as pieces of paper. A piece of paper can have some primitive value on it, such as a number, or it can have a house address1. Imagine these steps:

  • Build a house
  • Write the address of that house on a piece of paper (sc1)
  • Copy the writing on sc1 onto another piece of paper (sc2)
  • Rub out the address on sc1
  • Visit the house whose address is on sc2

That's similar to what you're doing here... and clearly rubbing out the value on sc1 doesn't affect either the house or the sc2 piece of paper.

Now as for why you see 2 and then 1... imagine these steps:

  • Build a house
  • Write the address of that house on a piece of paper (sc1)
  • Use sc1 to find the house, and put two parcels on the doorstep
  • Copy the writing on sc1 onto another piece of paper (sc2)
  • Use sc1 to find the house, and shout out how many parcels you find
  • Use sc1 to find the house, and take one parcel away
  • Use sc2 to find the house, and shout out how many parcels you find

The first time you'll shout 2, and then you'll shout 1. You're not changing the values on the pieces of paper - you're changing the house itself, by adding or removing parcels.


1 I know that references aren't memory addresses necessarily. This is purely for the sake of the analogy, which is one I've found helpful.

Upvotes: 12

Josip Medved
Josip Medved

Reputation: 3711

Let's just take a look where things point:

SomeClass sc1 = new SomeClass();

Here you have sc1 pointing (has a reference to) to your newly created class and sc2 is not even in picure.

SomeClass sc2 = sc1;

You have both sc1 and sc2 pointing to same object.

sc1=null;

Your object is still intact since sc2 is still pointing to it. Sc1 is null and not pointing to anything. Object itself is not eligible for garbage collection because of sc2.

sc2=null;

Now you have both sc1 and sc2 pointing to nothing. Your object has no references to it and garbage collector will (eventually) release it.

As you see from step-by-step, "reference link is broken" but object it self is not really affected until all its references are lost. As long as you have single reference to it, object is alive.

Upvotes: 0

Montolide
Montolide

Reputation: 792

If you make SomeClass sc1 = new SomeClass(), you make something like sc1->OBJECT. Doing sc2=sc1, is like making sc2->sc1->OBJECT, or sc2->OBJECT. So changing sc1 references doesn't change sc2.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

When you set sc2 to sc1, you copy the reference. The two variables reference the same object, but they do not become the same variable. Setting sc1 to null does not change sc2 - it references the same SomeClass object, so there is no NullPointerException when you access its getList() method.

Upvotes: 5

Related Questions