不可变的子类

我目前正在开发一个multithreading框架。 为了避免副作用,我想要求framewok操纵的所有数据必须是不可变的。

那么Java中是否存在一种方式来指定我希望给定类的所有子类或实现给定接口的所有类都是不可变的?

我建议研究Mutability Detector 。 它执行静态分析以确定给定的类是否是不可变的。 它可以用于添加类似于运行时断言的东西,即如果传递了一个可变类的实例,则可以选择抛出exception。 请注意,它可以在运行时分析实际的具体类,包括您定义的接口的子类或实现。

它仍然是1.0之前的版本,并且存在java.lang.String问题,但它可以使用。 如果它接近您正在寻找的东西,但并不完全符合您的要求,我建议您联系邮件列表或提交错误报告,因为我相信项目维护者是一个非常合理的人。 免责声明:维护者是我;-)

没有办法要求子类的不变性。 您可以通过不提供setter并保持实例变量私有来确保类的子类不会改变您的状态,但如果子类声明它们自己的实例变量,则它们可以完全控制它们。

就接口而言,你唯一能做的就是不提供setter。 但是,实现可以提供自己的setter。

为了使类真正具有可变性,该类的所有成员必须是不可变的,并且类本身必须是final 。 这样可以确保无法在类中或类外部更改对象。

为了使类中的成员不可变,这意味着不仅仅是让它们成为final 。 例如

 private final List strings = new LinkedList(); 

stringsfinal但仍然可以更改,因为可以在列表中添加和删除项目。 在这种情况下,您可以将其包装在不可修改的集合中。 即使这并不完美,因为列表中的对象可能是可变的( Strings显然不是很明显,但是你的列表中可能有可变对象,你可以在其中进行list.get(index).mutator(...)

关于如何使对象不可变,没有灵丹妙药。 如果它提供了任何改变对象的方法,那么它就不可能是不可变的。

至于上课final ,要实现有保障的不变性,这是必要的。 想象一下,

 class MyImmutableClass { private final String name } class MutableClass extends MyImmutableClass { private String mutableValue; public void setMutableValue(String mutableValue...) } void doSomething(MyImmutableClass c) {...} 

不能保证doSomething实际上是在处理一个不可变的实例,而是它可能正在处理一个可变的子类。 如您所见,这会对使用接口造成问题。 无法保证接口的实现者是不可变的。

@Immutable注释并不能保证不变性,而只是声明类告诉你它是不可变的,但没有好的方法来强制执行。

如果你能够在groovy中工作,那么@Immutable注释会产生一些效果,因为它提到了很多这些技术。 http://groovy.codehaus.org/Immutable+AST+Macro