Fra*_*fer 11 java oop immutability
在给我的问题具体化之前,让我提供一些背景知识:我的主要编程语言是C++和Java.使用C++时,我发现应用const正确性很重要,即声明这样的函数:
A::DoSomething( const B& arg ); // guarantees that arg is not modified
A::DoSomething() const; // guarantees that the object of type A is not modified
A::DoSomething( const B& arg ) const; // both of the above
Run Code Online (Sandbox Code Playgroud)
事实上,我经常希望这const是默认值,并且必须以某种方式标记被修改的对象.
我使用的主要原因const是:
众所周知,Java没有const关键字(你不能做上面的事情final),这个事实在这里已经讨论过,例如参见:Java中的const(C++)的等价物.
通常提出的Java替代方法是使您的类不可变.虽然这不是完全替代,const因为它适用于每个类而不是每个使用类的上下文,但在大多数情况下它对我来说都可以正常工作.
但是不可变类有一个大问题:不可变性并不明显.要知道一个类是否真的是不可变的,据我所知,你基本上必须检查完整的源代码.任何方法都可以有一个后门,通过它可以修改对象.
那么有更简单的方法来检查不变性吗?或者是否有任何最佳实践以某种方式标记一个类是不可变的?
注意:我知道这两种语言都提供了绕过constness或immutability的"邪恶伎俩":C++ const_cast和Java都有反思.但是对于我的问题的背景,我们假设这些都没有被使用.
qww*_*sad 14
Java没有一流的不变性支持,所以你没有可靠的方法来检测类是否是不可变的.
Java Concurrency In Practice建议(参见附录A作为参考)使用类级@Immutable注释javax.annotation.concurrent,这是表示不变性的最方便,最常用和最标准的方法; 自定义javadoc也很好.请注意,它只是声明,而不是实际约束.
班级设计也是一个很好的指标:
this引用不会从构造函数中泄漏)可以在Oracle教程中找到不可变类设计属性的完整列表.
因此,要检查类是否是不可变的,首先要查看类级别注释和javadoc,然后才能查看实现本身.
为了提供额外的健全性检查(如果你认为注释为不可变类可能是错误的可变的),FindBugs(静态分析工具)有Mutability Detector插件,它有效地做了上面列出的相同的事情:检查类有@Immutable注释并验证(通过反思)所有不变性规则都得到满足(还有一些额外的东西,比如来自Guava等的不可变收集支持).可变性检测器也可以用作没有FindBugs的库,它允许你编写这样的测试:
@Test
public void testImmutable() {
assertImmutable(MyClass.class);
}
Run Code Online (Sandbox Code Playgroud)