所有不可变对象都可以重用吗?

时间:2013-09-23 03:47:44

标签: java oop immutability value-objects

从有效的Java书中,它指出“如果一个对象是不可变的,它总是可以被重用”。

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

此版本使用single String instance,而不是创建新版本 每次执行。此外,保证对象将是 由碰巧包含的同一虚拟机中运行的任何其他代码重用 相同的字符串文字。

下面的最终课程也是不可变的?点对象可以重复使用吗?

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;
 }

任何人都可以向我提供上述immutable class的示例,其中可以重用其对象/实例吗?我只是对可重用性如何发生感到困惑?

我能够与StringInteger类相关联,但不能与用户定义的类相关联。

3 个答案:

答案 0 :(得分:11)

它可以“重复使用”,因为你可以在多个地方使用同一个对象,这样就可以了。但它不会自动发生。 JVM本身管理重用Integer对象的范围为-128 - 127

Integers caching in Java

“实习”字符串(包括文字)同样由JVM管理。您可以在此处使用最接近自动重用的方法是将构造函数设置为私有,并创建工厂方法:

 Point.create(int x, int y)

让实现维护一个你想要重用的对象的缓存(比如整数有效地缓存-128到127)但是你必须自己做这项工作。

编辑:

你基本上有:

 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;
 }

编辑: 或者,将hashCode()和equals()添加到Point类,并使用HashSet。会更简单。

答案 1 :(得分:0)

可用仅仅意味着更改“引用”变量值。 例如可以重用int并更改其值 数据类型稍有不同,例如使用“新”实例重新启动参考变量,例如myframe = new JFrame() 声明为“final”的变量是“常量”并且是可变的。

上面的类本身要求它在引发时的引用变量被声明为“final”是可变的,尽管它的内容实际上是可变的,但难点是上下文的定义(变量或类定义)部分是可变的。 / p>

答案 2 :(得分:0)

不变性意味着当一个物体被创造时,它在创造时的状态将会延续其生命。是的,你展示的类和该类的对象是不可变的,因为你在构造函数中初始化状态并且没有setter。

关于重用:是的,您可以在需要Point类型的对象的地方重复使用相同的对象,但为此目的,您必须在为此创建对象时保留该对象。作为@James 建议,您可以使用工厂进行对象创建,并且工厂可以在您要求Point对象时决定是否需要创建新对象或使用现有对象。