4

从有效的 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它的对象/实例可以被重用吗?我只是对可重用性如何发生感到困惑?

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

4

3 回答 3

11

它“可以”重复使用,因为您可以在多个地方使用同一个对象,这很好。但它不会是,自动的。JVM 本身管理 -128 - 127 范围内的重用整数对象

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。会更简单。

于 2013-09-23T03:52:46.057 回答
0

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

上面的类本身要求它的引用变量在初始化时被声明为“final”是可变的,尽管它的内容实际上是可变的,困难在于定义哪个(变量或类定义)部分是可变的上下文。

于 2013-09-23T04:01:29.047 回答
0

不变性意味着当一个对象被创建时,它在创建时的状态将贯穿其整个生命周期。是的,您展示的类和该类的对象是不可变的,因为您在构造函数中初始化状态并且没有设置器。

关于重用:是的,您可以在需要 Point 类型的对象的地方一遍又一遍地重用同一个对象,但是为此目的,您必须在为此创建对象后保留该对象。正如@James 建议的那样,您可以使用工厂来创建对象,并且当您请求 Point 对象时,该工厂可以决定是否需要创建新对象或使用现有对象。

于 2013-09-23T04:21:40.977 回答