3

I was trying something, and I came across this interesting scenario. I just wanted to understand what is the major difference in these two snippets.

Initially, I took two sets, initialized one and assigned the reference to other. When I cleared set A, I noticed that Set B size changed to zero as well

Set<String> A = new HashSet<String>(); A.add("hello"); A.add("HEY"); A.add("hey"); Set<String > B = A; System.out.println("initial sizes :" + A.size() + " " + B.size()); A.clear(); System.out.println("final sizes :" + A.size() + " " + B.size()); 

The output of this was something like this :

initial sizes :3 3 final sizes :0 0 

Now, I tried to depict the same behavior for objects as follows:

Object a1 = new Object(); Object b1 = a1; System.out.println("initial sizes :" + b1.toString() + " " + a1.toString()); a1 = null; System.out.println("initial sizes :" + b1.toString() + " " + a1); 

The output for this was something like :

initial sizes :java.lang.Object@54182d86 java.lang.Object@54182d86 initial sizes :java.lang.Object@54182d86 null 

What is the exact difference here, I was expecting to get a NullPointerException when i tried to print b1.toString()

4
  • 3
    @ha9u63ar in java everything is passed as value, you might be right with the reference, but the reference to the object is passed as value aswell. Commented Feb 5, 2015 at 14:43
  • @KevinEsche I was editing my comment before you posted yours - Just spotted it. Apologies. Commented Feb 5, 2015 at 14:46
  • I am not sure how you got the output using Object in the code snippet - Have a look at this Commented Feb 5, 2015 at 14:52
  • A.clear() modifies the internal state of the object referred to by the reference A. a1 = null modifies the reference stored in a1, not the object it refers to. Commented Feb 5, 2015 at 17:55

5 Answers 5

4

For primitives such as int, double, float etc, a copy of the value is made and that is passed by value:-

int x = 10; public void foo(int k){ } foo(x) 

Here k will get a copy of the value stored in x so k will now have a value of 10. However, x and y are in two different memory locations. Changing the value of x will not change the value of k.

For object references a copy of the reference is made and that is passed by value (a reference is nothing more than the address of some memory). So in essence both references will now point to the same object (that is, the same memory location).

Myobject m = new Myobject(); public void bar (Myobject j){ } bar(m) 

A copy of the value of the reference m will be made and assigned to j. Both m and j will now point to the same object.

Sign up to request clarification or add additional context in comments.

Comments

3

The difference here, is that a1 and b1 are not the objects themselves but references to those objects. So, if you modify the object referenced by a1 the object referenced by b1 (which is the same object) will change too. If however you tell a1 to point to another instance (or null in this case) it will no longer reference the same object so changes to that won't effect b1.

To go into a little more detail: Java is pass by value. However when you try to pass an object (rather than a primitive value) you're actually passing the value of the reference (also sometimes called the handle). That's why it can sometimes be a bit confusing when trying to determine whether Java is pass by handle or pass by reference.

2 Comments

i would note obj1 = obj2 (both are at the same memory location) Where obj1.clone(obj2) they are both at different memory locations)
@DaveP You mean like "So, if you modify the object referenced by a1 the object referenced by b1 (which is the same object)..."?
2

Check this image. A2/A3 are REFERENCES to bojects. In first case these are references to Set (a1 on image). When one reference modifies object second reference sees the same change

On the other hand if you just set reference = null then you "erase one arrow" from the picture. The reference stops pointing to object, but the other reference still points to it.

enter image description here

Comments

0

You just noticed that java is completly pass by value, in which even references to other objects are passed as value.

If you null an object you are actually not nulling objects, which methods would be executed on the same object. You are only nulling the value of the reference to the object.

Check this example, you are just nulling the value of the reference on list 1, while you are still able to execute the methods on the original list.

ArrayList<Integer> list1 = new ArrayList<Integer>(0); list1.add(1); list1.add(2); ArrayList<Integer> list2 = list1; list1.clear(); list1 = null; System.out.println(list2.size()); System.out.println(list1.size()); // will cause an nullpointerexception 

The calls of methods on list1 does also effect list2, but nulling the object list1 wont affect the list 1

Comments

0

My answer is an additional element to @I.K. answer. Primitives (copy of value) and Non-Primitives (copy of reference values) - that's the key understanding.

Look at this code where I have put the comments (hosted on IDEONE):

import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */ class Ideone { public static void main (String[] args) throws java.lang.Exception { String a1 = "blablabla"; String b1 = a1; System.out.println(b1); System.out.println(a1); System.out.println(b1.hashCode()); System.out.println(a1.hashCode()); a1 = "wow"; System.out.println(b1.hashCode()); System.out.println(a1.hashCode()); System.out.println(b1); System.out.println(a1); Set<String> a = new HashSet<String>(); Set<String> b = a; a.add("hey"); a.add("HellO"); System.out.println(b.size()); System.out.println(b.hashCode()); // e.g. 69712814 System.out.println(a.hashCode()); // same - 69712814 (It's important to know) a.clear(); System.out.println(a.size()); // same hashcode i.e. gets affected by the change. System.out.println(b.size()); 

You can see that they are effectively hashed using the same code.

String class is a bit special in Java as you probably know that they use the String pool for "Intern"ing the values. If you run the code above you can see that as soon as you do a1 = "wow"; it will create a new value "wow" in the pool and therefore, the hashCode() changes.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.