0

Java never had immutable primitive arrays. However Java does have an immutable List or Map or other collection classes and of course final primitive fields and variables. In Java if you try to make an Object or array final you only make the reference final. The reference will only point to the same actual object but this does not make the underlying object immutable.

One advantage of immutable arrays would be not needing to create defensive copies because the array could be immutable anyway and could be trivially implemented in syntax:

final int[final] array = new int[final]{1, 2, 3, 4};

Is there a particular technical reason for allowing primitives and references to be made immutable but not arrays? What are the specific less obvious implications to immutable arrays that caused them to be left out of Java and why do they apply to arrays specifically but not primitives? What language or implementation features or mechanics are incompatible with immutable arrays and how so? What other parts of the language would not 'add up' if there were immutable primitive arrays?

3
  • 1
    final makes the variable immutable, not the value it holds. Primitive values are always immutable. Objects may or may not be immutable depending on their implementation. Arrays are "special" in Java. They are not instances of classes and cannot be inherited, so there is no place to put metadata that would distinguish an immutable array from a regular array. Array item access cannot be overridden but is directly compiled to special-purpose bytecode instructions. In short, it is not realistic to change how arrays work, since they are baked into the fundamentals of the language.
    – JacquesB
    Commented Jun 24, 2023 at 8:45
  • 2
    @JacquesB 'there is no place to put metadata that would distinguish an immutable array from a regular array' That is a fact, not an opinion. Your comment could be a valid, fact-based answer to the question. As such, I do not find my question 'opinion-based.'
    – CPlus
    Commented Jun 24, 2023 at 19:27
  • 2
    @user16217248-OnStrike: I totally agree, I don't think it is opinion-based at all. I think some users close any language-design question because they mistakenly think language design is purely subjective, as if language designers just pick a random set of features and stick them together. But in fact, much language design follows by logical necessity from more fundamental design choices and constraints.
    – JacquesB
    Commented Jun 25, 2023 at 11:02

3 Answers 3

6

Arrays are "special" in Java. They are not implemented as a class with constructor and members. Instead array creation and array operations (like reading and writing elements) are compiled directly into special-purpose bytecode instructions.

This means there is no way to override array behavior to create variants with different behavior. It is not that immutability in particular was left out, it is that arrays are designed to not support any kind of customization or parameterization beyond the element type.

This is for performance reasons. Arrays are the internal data structure behind all other collection types, so performance is critical. Any runtime overhead on element access, like calling a virtual method (or just checking a "mutable" flag on the instance) would have a significant impact across the board.

The way to customize array behavior is to create a wrapper class which encapsulate all access to the the array - and this is what the immutable containers like ImmutableList<E> does. Arrays have some other drawbacks (they are not fully type safe) which means generic collections should be preferred to working directly with arrays anyway.

4
  • Arrays are not the internal data structure behind all other collection types: java.util.LinkedList is an example.
    – Bossie
    Commented Jan 18 at 21:00
  • The JLS could define a new type, "Immutable Array", with OP's syntax, if it wanted to. However that would be a different type to mutable arrays, and it wouldn't be sound for it to be assignable to/from mutable arrays, which would limit it's usefulness.
    – Caleth
    Commented Jan 22 at 15:09
  • @Caleth Array-operations have dedicated bytecode instructions, so you can't just add a new kind of array at the Java language level.
    – JacquesB
    Commented Jan 24 at 7:10
  • @JacquesB Can't language changes go along with bytecode changes? Even if not, I would think you could re-use (a subset of) the existing array bytecode
    – Caleth
    Commented Jan 24 at 8:59
0

An array can be immutable (final) just like anything else. That doesn't mean the elements it holds are immutable.

That's no different from Collections. Just because a Collection is immutable doesn't mean its constituent elements are immutable.

5
  • 1
    You cannot make an array immutable. Using final on a variable or field of an array type will not make the array immutable, it just means the variable cannot be assigned a different array after first assignment. The elements may be immutable values (e.g primitives) but the array itself cannot be immutable - you will always be able to replace the value at a given index.
    – JacquesB
    Commented Jun 30, 2023 at 10:20
  • @JacquesB you don't understand what immutable means in the context of Java. It means exactly that, that you can't reassign something. It NEVER means you can't change the content of a variable. So yes, the array variable IS immutable, but that doesn't mean the array elements are fixed. Same with anything, and not just arrays and Collections.
    – jwenting
    Commented Jun 30, 2023 at 13:21
  • "mutable" and "immutable" is commonly used to refer to whether an object's state can be modified after creation. For example, strings are described as immutable while string buffers are mutable. Java has both mutable and immutable collections, for example, List.of(...) will give you an immutable collection, which means you can't change what elements it contains.
    – JacquesB
    Commented Jun 30, 2023 at 14:47
  • 2
    @JacquesB That's all a matter of semantics. Is a final int immutable? What if I tell you it represents a person in a class, does the fact that person can (and likely will all the time) change itself, in any way detract from the int's immutability? Even deep immutability is only so deep. Commented Jun 30, 2023 at 20:25
  • @Deduplicator: Primitive values in Java are immutable. It does not matter what the value "represent", what matters is if the value can change state at runtime.
    – JacquesB
    Commented Jul 2, 2023 at 13:50
0

You're treating arrays as something separate from "primitives and references". That's your problem right now... arrays are references... they're a special kind of object, but fundamentally they're still just objects allocated off the heap.

So declaring them final has exactly the same effect as on any other object reference... i.e. the reference cannot be re-assigned, but like any other object, the object's mutability depends on the object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.