0

Consider the following snippet:

public class TestBench {

    private static final short matrix[][] = new short[][] {new short[] {}};

    public static void main (String args[]) {
        matrix = new short[][] {new short[] {}}; // illegal
        matrix[0] = new short[] {}; // ok
    }
}

Is there a way to make that sub array final? While reading the similar questions, I realised I can do this with a custom class, but I'm curious about using primitive types.

Thanks in advance.

GuiRitter
  • 697
  • 1
  • 11
  • 20

4 Answers4

2
private static final short[] subArrray = new short[] { };
private static final short matrix[][] = new short[][] { subArray };
Juvanis
  • 25,802
  • 5
  • 69
  • 87
  • Nope, `matrix[0] = new short[] {};` still works. `subArray` is final, but I can still replace it in `matrix`. According to what I suspected and others confirmed, it's impossible. – GuiRitter Sep 01 '13 at 03:20
1

If you are trying to create an array whose cells (or subarrays) cannot be changed, you are out of luck. The cells of a Java array are always mutable.

If you need immutability at that level, your best option is to create an immutable wrapper class for the array:

  • For a 1-D array, I'd recommend Collections.unmodifiableList, or Guava immutable collections. (The distinction between immutable and unmodifiable could be significant.)

  • For an array with higher dimensions, you may need to build a custom class to represent the data structure with the desired characteristics. There are existing implementations out there, but they may not have the right model for your use-case. (Search for "java immutable matrix" and so on.)

If you are happy with the data structure as is (and its mutability characteristics), and you are trying to address the compilation error in the example, read on.

The problem with your current attempt is actually nothing to do with the way that primitives or arrays work. The problem is simply that you are trying to assign to a final after it has been initialized. You can't do that Java.

There are two solutions in this particular case:

  • If the initialization (e.g. the arrays' sizes) does not depend on anything that main is supplying, simply move the array initialization into the classes static initialization; e.g. as proposed by Juvanias.

  • If the initialization depends on stuff in main, then you will need to make the array variables into final instance variables, and do the initialization in a constructor.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I think you misread the OP's question. The OP _wants_ the compiler error to occur, even when assigning the array element. – C. K. Young Sep 01 '13 at 02:18
  • @ChrisJester-Young - I have addressed that too. I'm not convinced we really understand what he is asking. – Stephen C Sep 01 '13 at 02:27
  • @ChrisJester-Young is right. That was my objective. But thanks for confirming my suspicions. Also, I liked the "The cells of a Java array are always mutable.". I didn't knew that. – GuiRitter Sep 01 '13 at 03:22
1

Array elements are always mutable. There is no way to make them final, sorry.

As an aside, it is for this reason that EnumType.values() (where EnumType is an enum type) will always defensively copy the internal values array before returning, because there is no way to make the internal values array immutable.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
1

Keep in mind, the final modifier restricts access to the variable. It's not a modification of the type of the variable, but instead of the variable itself. As a result, it's only used to describe field declarations, rather than to describe expressions or types.

If you wanted the values inside the array to be immutable (like types described with const in c++) you'd need to use a custom class.

In general, java doesn't have a whole lot of const-related typing. They don't even include anything like const into their type system. Instead they rely on information hiding to achieve the same protection. I.e. hiding fields with private or protected so that people can't assign to them from outside the class.

zjagannatha
  • 336
  • 2
  • 5