2013-09-01 2 views
0

Рассмотрим следующий фрагмент кода:Java: Как сделать окончательный подмассив?

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 
    } 
} 

Есть ли способ сделать что окончательное суб массив? При чтении подобных вопросов я понял, что могу сделать это с помощью специального класса, но мне любопытно использовать примитивные типы.

Заранее спасибо.

ответ

1

Элементы массива всегда изменяемы. Невозможно сделать их окончательными, извините.

Как и в стороне, именно по этой причине, что EnumType.values() (где EnumType является enum типа) будет всегда защищаясь копировать внутренний массив значений, прежде чем вернуться, потому что нет никакого способа, чтобы внутренние значения массива неизменен.

2
private static final short[] subArrray = new short[] { }; 
private static final short matrix[][] = new short[][] { subArray }; 
+0

Нет, 'matrix [0] = новый короткий [] {};' все еще работает. 'subArray' является окончательным, но я все еще могу заменить его в' matrix'. Согласно тому, что я подозревал, и другие подтвердили, это невозможно. – GuiRitter

1

Если вы пытаетесь создать массив, чьи ячейки (или подмассивы) не могут быть изменены, вам не повезло. Ячейки массива Java всегда изменяемы.

Если вам нужна неизменность на этом уровне, лучший вариантом является создание класса immutable обертки для массива:

  • Для массива с 1-D, я бы рекомендовал Collections.unmodifiableList или гуавы неизменных коллекции , (Различие между неизменяемыми и неизменяемыми может быть значительным.)

  • Для массива с более высокими размерами может потребоваться создать пользовательский класс для представления структуры данных с требуемыми характеристиками. Существуют существующие реализации, но у них может не быть подходящей модели для вашего прецедента. (Поиск «Java неизменной матрица» и так далее.)

Если вы счастливы со структурой данных, как это (и его переменчивость характеристики), и вы пытаетесь решить ошибку компиляции в примере, читай дальше.

Проблема с вашей текущей попыткой на самом деле не связана с тем, как работают примитивы или массивы. Проблема в том, что вы пытаетесь назначить final после того, как она была инициализирована. Вы не можете сделать эту Java.

Есть два решения в данном конкретном случае:

  • Если инициализация (например, размеры массивов) не зависит ни от чего, что main является подачи, просто переместить инициализацию массива в классы статической инициализации ; например как было предложено Juvanias.

  • Если инициализация зависит от материала в main, тогда вам нужно будет сделать переменные массива в переменные экземпляра final и выполнить инициализацию в конструкторе.

+0

Я думаю, вы неправильно поняли вопрос OP. OP _wants_ возникает ошибка компилятора, даже при назначении элемента массива. –

+0

@ ChrisJester-Young - Я тоже обратился к этому. Я не уверен, что мы действительно понимаем, что он спрашивает. –

+0

@ ChrisJester-Young - это правильно. Это была моя цель. Но спасибо за подтверждение моих подозрений. Кроме того, мне понравилась «Ячейки массива Java всегда изменяемы». Я этого не знал. – GuiRitter

1

Имейте в виду, что модификатор final ограничивает доступ к переменной. Это не модификация типа переменной, а вместо самой переменной. В результате он используется только для описания описаний полей, а не для описания выражений или типов.

Если вы хотите, чтобы значения внутри массива были неизменяемыми (например, типы, описанные с const в C++), вам нужно будет использовать собственный класс.

В целом, у java нет большого количества const-связанных типов. Они даже не включают ничего подобного const в свою систему типов. Вместо этого они полагаются на информацию, скрывающуюся для достижения такой же защиты. То есть скрывая поля с private или protected, чтобы люди не могли назначать их извне класса.