ACP
ACP

Reputation: 1

Why is a private variable of type HashSet is being shared among object instances of the class?

I recently stumbled upon this weird behaviour of Java where a variable of type Hashset, which is declared private in the parent class, is not unique for each instance of the child. Instead, all the instances are pointing to the same private variable and modifying for one instance is reflecting for all. However, It is unique if we have instances from two classes inherited from the same parent.

Please find the Class structure below.

Public Class Main { 
private Set<String> test = new HashSet();
protected void addToTest (String s){test.add(s);} 
}

Public Class Child1 extends Main { }

Public Class Child2 extends Main{ }
  1. If we have two instances of the same class inheriting Main Class.
Main o1 = new Child1(); 
Main o2 = new Child1();

o1.addToTest("test"); 
o2.addToTest("test");

o1.clear();
//If we clear from one object is clearing at both the places, and both the object's hashcode of the variable test is same.
  1. If we have two instances of the different classes inheriting Main Class.
Main o1 = new Child1(); 
Main o2 = new Child2();

o1.addToTest("test");
o2.addToTest("test");

o1.clear();
//If we clear from one object is not clearing at both the places, and both the object's hashcode of the variable test is different

Can someone help me understand why the behaviour is different? Also, I was under the assumption that if a variable is declared private, it should be unique to that instance, but here it is not;

Why the instance variables are not unique here?

Upvotes: -1

Views: 90

Answers (2)

akop
akop

Reputation: 7871

Your observations are wrong. Here is a proof, that the instances of your HashSet<> are unique.

Screenshot of Onecompiler https://onecompiler.com/java/3zu25qwu4

Maybe you posted different code?

Upvotes: 0

Stephen C
Stephen C

Reputation: 719386

The test variable is an instance variable, that means that each and every instance of Main, Child1 and Child2 will have its own test variable. And given the way that you are initializing test, they will all have their own distinct HashSet objects. This is just how instance variables work.

If you want the objects to share a HashSet, then either the set must be passed in from the outside (e.g. via a constructor argument) or you need to make test a static variable.

Note: using static is not very OO and it leads to various practical problems. The larger your application is, the more problematic static state can be.


As far as your example is concerned where you claim that the HashSet is shared between two instances of Child1, I can say with confidence that you are mistaken.

Unfortunately, what you have shown us is not a proper minimal reproducible example, so we can't run your (actual) code to see for ourselves (or not) the evidence that you are seeing. If we can't see it, we can't definitively explain it.

In the absence of actual evidence, I expect that the explanation will be one of the following:

  • You have actually declared test as static.
  • You have misinterpreted the output of the code (which you haven't shown us!) that allegedly shows the sharing.
  • You've made a mistake ... such as not recompiling code after making changes ... so that the compiled code that you are actually running doesn't match the source code you are looking at. (That is an easy mistake to make if you are unfamiliar with the tools you are using.)

Upvotes: 2

Related Questions