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

Каков смысл окончательного ArrayList?

Какие преимущества/недостатки мы можем получить, сделав окончательный выпуск ArrayList (или другой коллекции)? Я все еще могу добавить в ArrayList новые элементы, удалить элементы и обновить их. Но каков эффект, делающий это окончательным?

4b9b3361

Ответ 1

Но каков эффект, делающий его окончательным?

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

final List<Integer> list = new ArrayList<Integer>();
list = new ArrayList<Integer>(); // Since `list' is final, this won't compile

В качестве стиля я объявляю большинство ссылок, которые я не намерен изменять как final.

Я все еще могу добавить в ArrayList новые элементы, удалить элементы и обновить их.

Если вы хотите, вы можете предотвратить установку, удаление и т.д., используя Collections.unmodifiableList():

final List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>(...));

Ответ 2

Это просто означает, что вы не можете повторно назначить свою ссылку. Попытка сделать что-то вроде приведенного ниже приведет к ошибке компилятора.

final List<String> list = new ArrayList<String>();

list = new LinkedList<String>();
     ^
     Compiler error here

Если вам действительно нужен неизменный список, вы должны использовать метод Collections.unmodifiableList().

Ответ 3

Вы не сможете изменить свою ссылку, используя new ArrayList, например.

Ответ 4

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

Если вы комбинируете ключевое слово final с помощью Collections.unmodifiableList, вы можете определить поведение, которое, вероятно, пытаетесь достичь, для пример:

final List fixedList = Collections.unmodifiableList(someList);

Это приводит к тому, что список, на который указывает fixedList, не может быть изменен. Остерегайтесь, однако, что это все равно может быть изменено с помощью ссылки someList (поэтому убедитесь, что после этой привязки она выходит за пределы области.)

Ответ 5

Это не влияет на то, что вы можете сделать с ArrayList по своему усмотрению - сам ArrayList по-прежнему изменен. Вы только что сделали ссылку неизменной.

Но создание переменной final имеет другие преимущества:

  • Это предотвращает изменение переменной, если она будет оставаться постоянной. Это может помочь предотвратить будущие ошибки.
  • Создание переменных final может помочь компилятору выполнить определенные оптимизации производительности.

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

Ответ 6

final имеет много последствий при многопоточности.

  • JMM четко определяет завершение инициализации поля final.

Что не ясно определено:

  • Составители могут свободно переупорядочивать их через барьеры памяти.
  • Компиляторы всегда могут читать кешированную копию.

Ответ 7

Финал - это ключевое слово или зарезервированное слово в java и может применяться к переменные-члены, методы, класс и локальные переменные в Java. Однажды ты сделать контрольный финал, вам не разрешено изменять эту ссылку и компилятор проверит это и поднимет ошибку компиляции, если попытается для повторной инициализации конечных переменных в java.

Ответ 8

Вы не можете переустановить его в другую коллекцию, как сказал aix.

Пример: В сочетании с неизмененной реализацией списка вы получаете безопасных членов, которые вы можете сделать общедоступными.

Пример: Когда вы полагаетесь на эту ссылку, она не меняется, вам нужно финал. Это верно, например, в сценариях синхронизации.

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

Ответ 9

Я лично отмечаю поле коллекций моих классов как final, чтобы сохранить пользователей моего класса от проверки, является ли он нулевым или нет. Это работает, потому что, как только значение уже назначено конечной переменной, оно никогда не может быть переназначено другому значению, включая null.

Ответ 10

Чтобы получить действительно неизменный список, вам нужно будет сделать глубокие копии содержимого списка. UnmodifiableList будет только отображать список ссылок несколько неизменным. Теперь создание глубокой копии списка или массива будет жестким по памяти с ростом размера. Вы можете использовать сериализацию/десериализацию и хранить глубокую копию массива/списка во временном файле. Установщик не будет доступен, так как элемент varaible должен быть неизменным. Геттер будет сериализовать переменную-член в файл, а затем десализировать ее, чтобы получить глубокую копию. Серализация имеет врожденный характер проникновения в глубины дерева объектов. Это обеспечит полную неизменность при некоторых эксплуатационных расходах.

 package com.home.immutable.serial;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public final class ImmutableBySerial {

    private final int num;
    private final String str;
    private final ArrayList<TestObjSerial> immutableList;

    ImmutableBySerial(int num, String str, ArrayList<TestObjSerial> list){
        this.num = num;
        this.str = str;
        this.immutableList = getDeepCloned(list);
    }

    public int getNum(){
        return num;
    }

    public String getStr(){
        return str;
    }

    public ArrayList<TestObjSerial> getImmutableList(){
        return getDeepCloned(immutableList);
    }

    private ArrayList<TestObjSerial> getDeepCloned(ArrayList<TestObjSerial> list){
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        ArrayList<TestObjSerial> clonedObj = null;
        try {
             fos = new FileOutputStream(new File("temp"));
             oos = new ObjectOutputStream(fos);
             oos.writeObject(list);
             fis = new FileInputStream(new File("temp"));
             ois = new ObjectInputStream(fis);
             clonedObj = (ArrayList<TestObjSerial>)ois.readObject();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                oos.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return clonedObj;
    }
}

Ответ 11

По сути, вы пытаетесь достичь здесь, чтобы сделать список неизменным, я думаю. Однако, когда вы отмечаете окончательный список ссылок, это означает, что ссылка can not указана на любой другой объект списка, отличный от этого.

Если вы хотите, чтобы конечный (неизменный) ArrayList отправился вместо этого в утилиту класса Collections.unmodifaibleList(list).