Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are all immutable objects re-usable?

From the effective Java book it states that "An object can always be reused if it is immutable".

String s = "shane";
String p = "shane";

This version uses a single String instance, rather than creating a new one each time it is executed. Furthermore, it is guaranteed that the object will be reused by any other code running in the same virtual machine that happens to contain the same string literal.

What about the below final class which is also immutable?. Can the Point Object be re-used?.

public final class Point {
  private final int x, y;

  public Point(int x, int y) {
   this.x = x;
   this.y = y;
  }

  public int getX() { return x; }
  public int getY() { return y;
 }

Can anyone provide me an example of the above immutable class where its object/instance can be re-used?. I am just confused on how the re-usability would occur?.

I am able to relate with String and Integer Classes, but not with user defined classes.

like image 916
Shane Avatar asked Dec 19 '22 23:12

Shane


1 Answers

It "can" be reused, in that you could use the same object in multiple places and it would be fine. But it won't be, automatically. The JVM itself manges reuse Integer objects for the range -128 - 127

Integers caching in Java

"intern"ed strings (including literals) similarly are managed by the JVM. The closest to automatic reuse you could have here would be to make the constructor private, and create a factory method:

 Point.create(int x, int y)

And have the implementation maintain a cache of objects that you'd like to reuse (like Integers effectively cache -128 to 127) But you'll have to do the work yourself.

Edit:

You'd basically have:

 private static final Map<Pair<Integer, Integer>, Point> cache = new HashMap<>();

 public Point create(int x, int y) {
   Pair<Integer, Integer> key = Pair.of(x, y);
   if (cache.containsKey(key)) {
     return cache.get(key);
   }
   Point p = new Point(x, y);
   cache.put(key, p);
   return p;
 }

Edit: Alternatively, add hashCode() and equals() to the Point class, and just use a HashSet. Would be simpler.

like image 52
James Avatar answered Jan 04 '23 14:01

James