How to find out if a class is immutable

immutability, java, oop

Solution

Java has no first-class immutability support, so you have no reliable way to detect if class is immutable.

Java Concurrency In Practice recommends (see Appendix A as reference) to use class-level `@Immutable` annotation from `javax.annotation.concurrent` and this is the most convenient, common and standard way to indicate immutability; custom javadoc is fine too. Note that it's only declaration, not actual constraint.

Design of the class is also a good indicator:

- Have only final fields (but in rare cases it's possible to have some non-final fields and still be immutable, for example see String#hashCode)

- It's properly constructed (`this` reference doesn't leak from constructor)

- Object state cannot be modified (so class should not have setters and mutator methods)

- Don't store external (passed to constructor) references to mutable objects (e.g. create defensive copy of passed collection argument)

Full list of immutable class design properties can be found in Oracle tutorials.

So, to check if class is immutable you first look at class level annotations and javadoc and only then at implementation itself.

To provide additional sanity-check (if you think that annotated as immutable class can be mutable by mistake), there is Mutability Detector plugin for FindBugs (static analysis tool), which effectively doing same thing listed above: checks class has `@Immutable` annotation and verifies (via reflection) that all immutability rules are satisfied (with some additional things like immutable collection support from Guava etc.). Mutability detector also can be used as library without FindBugs, which allows you to write tests like that:

@Test
public void testImmutable() {
    assertImmutable(MyClass.class);
}

Problem

Before concretizing my question, let me provide some background: My main programming languages are C++ and Java. When working with C++ I find it important to apply const correctness, that is declaring functions like this: ``` 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 ``` In fact, I often wish that `const` would be the default and objects that are modified have to be marked somehow. My main reasons for using `const`are: - Communication with other developers: It makes code more expressive. - Communication with the compiler: It helps to find issues at compile time and sometimes makes additional optimizations possible. It is well-known that Java has no `const` keyword (you can't do the above with `final`) and this fact has been discussed here before, see for example here: Equivalent of const(C++) in Java. The Java alternative that is usually proposed is to make your classes immutable. While this is not a full replacement of `const` because it works per class and not per context in which a class is used, it would work fine for me in most cases. But there is one big issue with immutable classes: Immutability is not obvious. To find out if a class really is immutable, as far as I know, you basically have to check the full source code. Any method could have a backdoor through which the object could be modified. So is there an easier way to check immutability? Or is there any best practice to somehow mark a class as being immutable? Note: I know that both languages provide 'evil tricks' to bypass constness or immutability: C++ has `const_cast` and Java has reflection. But for the context of my question, let's assume that these are not used.

Original source

Related problems