在我的代码中,我正在创建一个对象集合,这些对象将被各种线程以只有当对象不可变时才安全的方式访问。当尝试将新对象插入到我的集合中时,我想测试一下它是否是不可变的(如果不是,我会抛出异常)。
我能做的一件事是检查几种众所周知的不可变类型:
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; }
}
有没有某种方法(也许使用反射),我能够可靠地检测一个类是否是不可变的?误报(认为它是不可变的,但实际上不是)是不可接受的,但漏报(认为它是可变的,但实际上不是)是可以的。
编辑补充:感谢提供深入见解和有用答案。正如一些答案所指出的那样,我忽略了定义我的安全目标。这里的威胁是无知的开发者-这是一段将被大量人使用的框架代码,他们对线程几乎一无所知,并且不会阅读文档。我不需要防范恶意开发者-任何聪明到足以 更改字符串 或进行其他花招的人也会聪明到知道在这种情况下不安全。对代码库进行静态分析是一种选择,只要自动化就可以,但不能依赖代码审查,因为不能保证每个审查人员都具备线程方面的知识。