Подтвердить что ты не робот

Конечный массив в Java

Следующий код в Java использует массив final String, и в этом нет сомнений.

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

Он отображает следующий вывод на консоли.

I can never change

Следующий код также не вызывает вопросов.

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    //CONSTANT_ARRAY={"I", "can", "never", "change"}; //Error - can not assign to final variable CONSTANT_ARRAY.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

Очевидно, что прокомментированная строка вызывает указанную ошибку, потому что мы пытаемся переназначить объявленный массив final типа String.


Как насчет следующего кода.

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    CONSTANT_ARRAY[2] = "always";  //Compiles fine.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

и отображает I can always change означает, что нам удалось изменить значение массива final типа String. Можем ли мы когда-либо изменить весь массив таким образом, не нарушая правило final?

4b9b3361

Ответ 1

final в Java влияет на переменную, она не имеет ничего общего с объектом, который вы назначаете ему.

final String[] myArray = { "hi", "there" };
myArray = anotherArray; // Error, you can't do that. myArray is final
myArray[0] = "over";  // perfectly fine, final has nothing to do with it

Изменить добавление комментариев: Обратите внимание, что я сказал объект, который вы ему назначили. В Java массив - это объект. Это же относится и к любому другому объекту:

final List<String> myList = new ArrayList<String>():
myList = anotherList; // error, you can't do that
myList.add("Hi there!"); // perfectly fine. 

Ответ 2

Вы неверно истолковываете окончательную реализацию. final применяется к ссылке на объект массива, что означает, что после ее запуска ссылка никогда не может измениться, но массив может быть заполнен. "Не нарушая правил", вы указали только одно правило относительно эталонного изменения, которое работает соответственно. Если вы хотите, чтобы значения также никогда не менялись, вы должны пойти на Неизменяемые списки i.e

List<String> items = Collections.unmodifiableList(Arrays.asList("I", "can", "never", "change"));

Ответ 3

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

Ответ 4

Когда вы объявляете массив как final, вы можете изменять элементы в массиве, однако вы не можете изменить ссылку этого массива.

Ответ 5

final гарантирует неизменность примитивов. А также гарантирует, что переменная назначается только один раз. Если объект изменен, вы можете изменить содержимое его события, которое оно определило как окончательное. Вы можете проверить неизменяемые коллекции для своих нужд. Например, Collections.unmodifiableList() http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList(java.util.List)

Ответ 6

Ссылка на объект массива окончательна (не может быть изменена, например, если вы попытаетесь связать другой объект массива Java (экземпляр String []) с той же конечной переменной... вы получите время компиляции ошибка).

НО поля конечного объекта массива в вашем примере не являются окончательными, поэтому вы можете изменить их значение.... в то время как созданный объект Java, CONSTANT_ARRAY, после получения начального значения, будет иметь это значение "навсегда" == до тех пор, пока JVM не остановится.:) Это будет тот же экземпляр String Array "навсегда".

Заключительные переменные в Java - это не большая проблема, просто потратьте некоторое время, чтобы тщательно пересмотреть тему/идею.:-)
Я предлагаю всем тем, кто не уверен в медитации на этой странице, например: https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

Позвольте мне привести соответствующую часть:

" Когда конечная переменная была назначена, она всегда содержит одно и то же значение. Если конечная переменная содержит ссылку на объект, тогда состояние объекта может быть изменено с помощью операций над объектом, но переменная всегда будет ссылаться на один и тот же объект.

Это относится также к массивам, поскольку массивы являются объектами; если конечная переменная содержит ссылку на массив, то компоненты массива могут быть изменены с помощью операций над массивом, но переменная всегда будет ссылаться на один и тот же массив. "

Ответ 7

Значение переменной CONSTANT_ARRAY не может измениться. Эта переменная содержит массив (ссылка на). Однако содержимое массива может измениться. То же самое происходит, когда вы объявляете какую-либо конечную переменную, которая не является простым скалярным типом (например, объектом).

Будьте осторожны, как вы называете переменные.:-) Вызов CONSTANT_ARRAY не делает содержимое массива неизменным.

Здесь хорошая ссылка: Последнее слово в финале

Ответ 8

    final int[] res;
    int[] res1;
    int[] res2 = new int[1];
    res2[0]=20;

    res1=res2;
    res1=res2;//no error
    System.out.println("res1:"+res1[0]);

    res = res2;//only once
   //res = res2;//error already initialised
    res2[0]=30;

    System.out.println("res:"+res[0]);     

Выход:: res1: 20 разрешение: 30