Как сделать мой код безопасным?- Частное против публичного - PullRequest
4 голосов
/ 03 декабря 2011

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

private ArrayList<SomeDataStructure> myPrivateArrayList;

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

public ArrayList<SomeDataStructure> getMyPrivateArrayList ();

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

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

Ответы [ 4 ]

6 голосов
/ 03 декабря 2011

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

private ArrayList<SomeDataStructure> myPrivateArrayList;

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

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

0 голосов
/ 03 декабря 2011

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

0 голосов
/ 03 декабря 2011

В вашей функции 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 голосов
/ 03 декабря 2011

Вместо типа возврата 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).)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...