But I didn't mention C++ :) (D and Rust have const too)
To be honest, I haven't looked much at Clojure. Do their containers/data structures use the immutable versions by default (kind of similar to what Scala does?)
The Rust programming language seems to have something going in that area. Immutability is the default, you have to explicitly declare mutable data members. Similar with methods, you have the option of declaring `self` to be mutable (which seems cleaner than C++'s approach).
Clojure only provides immutable data structures. Java, however, provides many mutable data structures which are readily available to Clojure. Clojure also provides mutable reference types that are tuned for particular concurrency patterns. Atoms for synchronous compare-and-swap, agents for asynchronous queues, etc.
There are no annotations to specify immutability, you have to trust whoever implemented the class you're using to provide the guarantees that are in their documentation. To some extent, that makes this a static vs dynamic typing discussion, but my point is that type annotations are realistically not necessary if you chose immutability as the default and provide a limited set of well known mutation operations. These operations are generally annotated with a "@", "!", or "." for "dereference current value", "side effectful", and "java interop" respectively.