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

Java Final arraylist

Мой вопрос в том, чтобы объявить arraylist окончательным. Я знаю, что как только я напишу окончательный ArrayList list = new ArrayList();, я могу добавить, удалить объекты из этого списка, но я не могу list = new ArrayList() или list = list1. Но что будет использовать объявление arraylist как Private static final ArrayList list = new ArrayList();. И помимо разницы, о которой я упомянул выше, какая разница между двумя декларациями:

1. ArrayList list = new ArrayList()

2. private static final ArrayList list =  new ArrayList();
4b9b3361

Ответ 1

Вы правы, что объявление окончания list означает, что вы не можете переназначить переменную list на другой объект.

Другой вопрос (я думаю) был

public class SomeClass {
    private static final ArrayList list = new ArrayList();
}

против

public class SomeClass {
    ArrayList list = new ArrayList();
}

пусть поочередно принимать каждый модификатор.

private Значит, только этот класс (SomeClass) может получить доступ к list

static Указывает, что для всех экземпляров SomeClass существует только один экземпляр переменной list. Экземпляр списка связан с классом SomeClass, а не с каждым новым экземпляром SomeClass. Если переменная нестатическая, она считается переменной экземпляра

final, как вы знаете, означает, что вы не можете переназначить переменную списка другим значением.

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

Вы можете узнать больше о public, private и package-private здесь: Контроль доступа

Вы можете узнать больше о final и static здесь: Переменные класса

Ответ 2

Чтобы "принести немного воды на мельницу", вы поймете интерес к финалу, когда захотите сделать свой список общедоступным, но не поддающимся редактированию.

В java можно сделать список немодифицированным с Collections.unmodifiableList(modifiableList).

Теперь взгляните на следующий код:

public class MyClass{
  public static List<String> MY_PUBLIC_LIST;
  static{
    ArrayList<String> tmp = new ArrayList<String>();
    tmp.add("a");
    tmp.add("b");
    tmp.add("c");
    MY_PUBLIC_LIST = tmp;
  }
}

Ну, в любом классе, в любом месте вашего кода вы можете сделать что-то вроде этого

MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");

Когда вы добавляете ключевое слово final в свою переменную, первая буксировка не будет разрешена

public static final List<String> MY_PUBLIC_LIST;

Но вы все равно сможете изменить содержимое списка:

MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");

Добавив Collections.unmodifiableList(modifiableList) в конце статического блока, вы тоже это предотвратите:

MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);

Хорошо, мы почти там. Просто чтобы убедиться, что вы получите всю картину, сохраните Collections.unmodifiableList(modifiableList), но позвольте мне удалить последний модификатор

public class MyClass{
  public static List<String> MY_PUBLIC_LIST;
  static{
    ArrayList<String> tmp = new ArrayList<String>();
    tmp.add("a");
    tmp.add("b");
    tmp.add("c");
    MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
  }
}

Что вы можете сделать в этом случае?

...

...

Ну, вы можете делать все, что хотите, как в первом случае (учитывая, что вы сначала назначаете новый список):

MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");

Ответ 3

Когда вы говорите

final ArrayList list = new ArrayList();

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

  • Вы хотите удостовериться, что no-one переназначает вашу переменную list после ее получения. Это может уменьшить сложность и помочь в понимании семантики вашего класса/метода. В этом случае вам обычно выгоднее использовать хорошие соглашения об именах и сокращать длину метода (класс/метод уже слишком сложный, чтобы его было легко понять).
  • При использовании внутренних классов вам необходимо объявить переменные как final в охватывающей области, чтобы вы могли получить к ним доступ во внутреннем классе. Таким образом, Java может скопировать вашу переменную final во внутренний объект класса (она никогда не изменит ее значение), а внутреннему объекту класса не нужно беспокоиться о том, что происходит с внешним объектом класса, пока объект внутреннего класса жив и нуждается для доступа к значению этой переменной.

Вторая часть вашего вопроса касается разницы между

ArrayList list = new ArrayList();

и

private static final ArrayList list = new ArrayList();

Разница, конечно, является модификаторами. private означает, что он не виден вне класса, static означает, что он определен на уровне класса и не нужен экземпляр для существования, а final обсуждается выше. Никакие модификаторы не означают пакетный или стандартный доступ.

Ответ 4

Вы говорите: "Я могу добавлять, удалять (и находить) объекты", но кто I?

Различие между двумя вашими случаями связано с тем, из какого кода можно вызвать эти операции списка.

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

Public Class MyThing {
   public int importantValue;

   // more code
}

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

Public Class MyThing {
   private int importantValue;

   public int getImportantValue(){
       return importantValue;
   }

   // more code
}

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

Использование static делает список общим для всех экземпляров класса, а не для каждого экземпляра, получающего его копию ovn.