2016-03-26 5 views
1

Если я что-то вродеЕсть ли способ сделать массив действительно приватным в Java?

private int[] myPrivateArray; 

и есть поглотитель, который возвращает массив, то содержимое массива может быть изменен из-за пределов класса, своего рода поражения цели, что делает его частным.

+1

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

+3

«Если у меня ... есть геттер, который возвращает массив» - * почему у вас есть это? Вам не нужен геттер для всего. – user2357112

+1

Оборонительные копии? То же самое и любое изменяемое состояние - если вы не хотите его раскрывать, вам нужно вернуть копии или неизменные объекты. –

ответ

3

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

4

Да, есть.

Во-первых, не предоставляйте геттер для этого массива, если вам это не нужно. Если вы ДОЛЖНЫ предоставить получателя, передайте копию, а не частную переменную.

Во-вторых, (до сих пор не учтено), убедитесь, что JVM SecurityManager настроен для остановки reflection.

2

Как уже говорили другие, вы можете вернуть копию массива:

public int[]getMyArray(){ 
    return myPrivateArray.clone(); 
} 

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

public int getMyArray(int index){ 
    return myPrivateArray.get(index); 
} 

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

public class MyClass{ 
    private Object[]myPrivateArray; 

    private List<Object>myArrayView=Collections.unmodifiableList(Arrays.asList(myPrivateArray)); 

    public List<Object>getMyArrayView(){ 
     return myArrayView; 
    } 
} 

Хотя это немного более сложным с массивом примитивов:

public class MyClass{ 
    private int[]myPrivateArray; 

    private List<Integer>myArrayView=new AbstractList<Integer>(){ 
     @Override public int size(){ 
      return myPrivateArray.length; 
     } 
     @Override public Integer get(int index){ 
      return myPrivateArray[index] 
     } 
    } 
    public List<Integer>getMyArrayView(){ 
     return myArrayView; 
    } 
}