1

I cannot fathom why Java wishes to hide immutable unmodifiable collections from being passed around.

It makes life harder on devs because you can't guarantee that a class is returning anything immutable unmodifiable, forcing you to smatter calls to Collections.unmodifiableWhatever throughout your code. This is both wasteful and annoying.

Is there a reason I'm missing behind why you would make these methods protected, or another library I'm missing that contains public versions of immutable and/or unmodifiable collections?

For the purposes of learning more about java, let's say Scala does not count as an answer to "a library that contains public versions of immutable collections" :)

kjb
  • 3,035
  • 3
  • 23
  • 30
  • 3
    Note that immutable and unmodifiable are two different things. – SLaks Feb 04 '14 at 22:15
  • @SLaks How so, and is this general terminology or Java jargon? –  Feb 04 '14 at 22:17
  • 2
    @delnan: "Immutable" means that the instance can never change. "Unmodifiable" (or "readonly") just means that _you_ can't change it, but that someone else might be able to. – SLaks Feb 04 '14 at 22:17
  • @SLaks Thank you! I'm wondering if I should perhaps be searching for a library that uses the immutable keyword. delnan: http://stackoverflow.com/questions/8892350/immutable-vs-unmodifiable-collection – kjb Feb 04 '14 at 22:18
  • Better not get into the definition of *immutable* because you'll soon realize that *nothing* is really immutable. – Marko Topolnik Feb 04 '14 at 22:18
  • @MarkoTopolnik - thats not true ;) – Алексей Feb 04 '14 at 22:19
  • @kjb: It depends what you want. – SLaks Feb 04 '14 at 22:19
  • 1
    @user1631616 A quick question for you: are `String`s immutable? – Marko Topolnik Feb 04 '14 at 22:19
  • @user1631616: You're forgetting about reflection – SLaks Feb 04 '14 at 22:20
  • @kjb: "a library that contains public versions of immutable collections" [Guava](https://code.google.com/p/guava-libraries/), perhaps? https://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained has some details on Guava's immutable collection types. – Louis Wasserman Feb 04 '14 at 22:21
  • @SLaks Strings can change even in the absence of reflection :) There was a blog about it, using the `new String(byte[], Charset)`, the `Charset` instance can be evil. – Marko Topolnik Feb 04 '14 at 22:21
  • @MarkoTopolnik can you post a link to the blog? using `new String(byte[], Charset)` eventually comes down to `Arrays.copyOf` – Алексей Feb 04 '14 at 22:33
  • I don't really understand why you should care about a collection to be unmodifiable unless it's part or the state of your object, that you want to protect and encapsulate. And if it's part of the state of your object, it's normally not part of the state of another object. So the other objects should not re-wrap the collection into an unmodifiable collection. – JB Nizet Feb 04 '14 at 22:39
  • @user1631616 Here is the link: http://stackoverflow.com/questions/11146255/create-a-mutable-java-lang-string. This loophole may have been closed when Java stopped sharing the `char[]` between strings. – Marko Topolnik Feb 05 '14 at 12:30

2 Answers2

2

I think it has to do with the design goals of the framework:

The main design goal was to produce an API that was small in size and, more importantly, in "conceptual weight."

(Source)

You should check out Guava's immutable collection types, if you are willing to learn more conceptual weight :)

lbalazscs
  • 17,474
  • 7
  • 42
  • 50
  • I guess it comes down to opinion on what it _should_ do, but if that is indeed what they're shooting for it at least explains the impetus behind making those classes protected – kjb Feb 04 '14 at 23:05
0

The Collections interface permits one to wrap an exiting Collection so that calls to mutator methods result in failure.

unmodifiableCollection(Collection c): "Returns an unmodifiable view of the specified collection."

It makes life harder on devs because you can't guarantee that a class is returning anything immutable, ... This is both wasteful and annoying.

The JDK source of the Collections.unmodifiableList() method is:

public static <T> List<T> unmodifiableList(List<? extends T> list) {
    return (list instanceof RandomAccess ?
            new UnmodifiableRandomAccessList<>(list) :
            new UnmodifiableList<>(list));
}

I see why this can be considered wasteful (these generics also make it ugly). Why doesn't that method check whether the passed instance is already an UnmodifiableRandomAccessList or UnmodifiableList?

David Tonhofer
  • 14,559
  • 5
  • 55
  • 51
  • I am asking _why_ it doesn't allow you to return a new type. The unmodifiableCollection methods use protected UnmodifiableXXX classes that are defined within the Collections source. Why not allow users to use them explicitly? – kjb Feb 04 '14 at 23:00
  • 1
    Usually what happens with these wrapped collections, is that they are wrapped again and again just to be on the safe side, which has performance implications. – lbalazscs Feb 04 '14 at 23:02
  • @lbalazscs exactly! This is why it is quantifiably wasteful, and, for anyone who isn't a robot, annoying. – kjb Feb 04 '14 at 23:04
  • @kjb I see. Adding some text. – David Tonhofer Feb 04 '14 at 23:11