如何在 Java 中识别不可变对象
在我的代码中,我正在创建一个对象集合,这些对象将由各种线程以一种只有在对象不可变时才安全的方式访问。当尝试将新对象插入到我的集合中时,我想测试它是否不可变(如果没有,我将抛出一个异常)。
我能做的一件事是检查一些众所周知的不可变类型:
private static final Set<Class> knownImmutables = new HashSet<Class>(Arrays.asList(
String.class, Byte.class, Short.class, Integer.class, Long.class,
Float.class, Double.class, Boolean.class, BigInteger.class, BigDecimal.class
));
...
public static boolean isImmutable(Object o) {
return knownImmutables.contains(o.getClass());
}
这实际上让我获得了90%的方法,但有时我的用户会想要创建自己的简单不可变类型:
public class ImmutableRectangle {
private final int width;
private final int height;
public ImmutableRectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() { return width; }
public int getHeight() { return height; }
}
有没有办法(也许使用反射)可以可靠地检测一个类是否不可变?误报(认为它是不可变的,当它不是)是不可接受的,但假阴性(认为它是可变的,当它不是)是。
编辑以添加:感谢您的有见地和有用的答案。正如一些答案所指出的那样,我忽略了定义我的安全目标。这里的威胁是无能为力的开发人员 - 这是一段框架代码,将被大量对线程几乎一无所知并且不会阅读文档的人使用。我不需要防御恶意开发人员 - 任何聪明到足以改变String或执行其他恶作剧的人也会足够聪明,知道在这种情况下它不安全。代码库的静态分析是一种选择,只要它是自动化的,但是代码审查不能指望,因为不能保证每次审查都会有精通线程的审查者。