Вопрос: Способ сделать мой код безопасным? - Частные и общественные


Экземпляр класса A имеет закрытый ArrayList. Экземпляр отвечает за сохранение данных, хранящихся в arrayList.

private ArrayList<SomeDataStructure> myPrivateArrayList;

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

public ArrayList<SomeDataStructure> getMyPrivateArrayList ();

Мой вопрос: как мне реализовать эту функцию, чтобы я мог гарантировать, что те, кто получает массивList через эту публичную функцию, не смогут ее модифицировать (т. Е. Возвращаемое значение только для чтения )?

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


4


источник


Ответы:


Я бы предложил сделать это вместо этого (если вам разрешено в вашей ситуации):

private ArrayList<SomeDataStructure> myPrivateArrayList;

public List<SomeDataStructure> getMyPrivateList () {
    return Collections.unmodifiableList(myPrivateArrayList)
}

Обратите внимание, что открытая структура данных имеет тип List вместо ArrayList, Я думаю (вообще говоря) публичный интерфейс класса не должен возвращать конкретные типы, а скорее должен возвращать интерфейсы. Он упрощает такие задачи, как этот, а также уменьшает количество зависимостей, которые один класс оказывает на реализацию другого класса.


6



Вместо возвращаемого типа ArrayList<SomeDataStructure>, используйте List<SomeDataStructure>, Затем вы можете использовать java.util.Collections.unmodifiableList(...) утилита-метод  для создания просмотра списка только для чтения:

public List<SomeDataStructure> getMyPrivateArrayList()
{
    return Collections.unmodifiableList(myPrivateArrayList);
}

Другой вариант - вернуть копию списка:

public ArrayList<SomeDataStructure> getMyPrivateArrayList()
{
    return new ArrayList<SomeDataStructure>(myPrivateArrayList);
}

(Есть и другие варианты, но это наиболее распространенные подходы.)

Но имейте в виду, что если SomeDataStructure может быть изменен, то вызывающие абоненты любого из указанных выше могут по-прежнему мутировать любой из объектов в вашем списке. (То есть, они могут сделать что-то вроде obj.getMyPrivateArrayList().get(0).setProp(null).)


0



В вашей getMyPrivateArrayList () выполните следующие действия:

public List<SomeDataStructure> getMyPrivateArrayList(){
    return Collections.unmodifiableList(myPrivateArrayList);
}

Collections.unmodifiableList(someList) возвращает список только для чтения.


В вашем вызывающем классе, если вы попытаетесь изменить возвращенный список, вы получите ошибку во время выполнения. например.

Если вы выполните следующее

List<SomeDataStructure> readOnlyList=getMyPrivateArrayList();
readOnlyList.add(new SomeDataStructure());

Вы получите следующую ошибку:

Exception in thread "main" java.lang.UnsupportedOperationException
  at java.util.Collections$UnmodifiableList.add(Collections.java:1160)
  at MainClass.main(MainClass.java:14)

0



Вам нужно получить список? Или вы можете просто переслать некоторые списки доступа в список? Вы можете определить некоторые публичные функции, такие как get(index) которые просто вызывают эквивалентные методы в вашем списке и возвращают результат. Это, скорее всего, то, что вы хотите сделать, потому что оно дает людям доступ только к выбранным вами методам, и вам не нужно давать им сам список или тратить циклы CPU, копируя данные в структуры «только для чтения».


0