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