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

Что такое Java-эквивалент функции-константы С++?

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

Есть ли способ сделать это в Java?

Если да, то как?

Я знаю о ключе final, но AFAIK, когда применяется к методу it:

  • Предотвращает переопределение/полиморфирование этот метод в подклассе.
  • Делает этот метод inline-able. (см. комментарий от @Joachim Sauer ниже)

Но он не ограничивает метод возвратом ссылки на элемент данных, так что он не может быть изменен вызывающим.

Я пропустил что-то очевидное?

4b9b3361

Ответ 1

Вы либо возвращаете объект неизменный, либо возвращаете копию переменной частного экземпляра. Таким образом, внутреннее состояние объекта "защищено" от модификации, то есть:

private MyMutableObject mutable = ...

public MyMutableObject getMutableObject() {
   return new MyMutableObject(this.mutable);
}
`

Ответ 2

Нет эквивалента модификатору типа C const "в Java (к сожалению).

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

Тем не менее, неизменяемость не является языковой особенностью Java, поэтому вам придется полагаться на библиотеки.

Примеры неизменяемых объектов:

  • примитивные обертки Integer, Character,..
  • String
  • File
  • URL

Обычно используемая неизменяемая оболочка (т.е. обертки вокруг изменяемых типов, которые предотвращают мутацию) - это те, которые возвращаются методы Collecton.unmodifiable*().

Ответ 3

Это не существует в java. final и const имеют разную семантику, кроме случаев применения к переменной примитивного типа. Java-решение обычно включает в себя создание неизменяемых классов - там, где объекты инициализируются в конструкции и не предоставляют доступа, позволяющих изменять. Пример таких классов будет, например, String или Integer.

Ответ 4

Вы ничего не пропустили. Для чистых Java это невозможно. Там могут быть библиотеки, которые предоставляют некоторые подмножества этого использования аннотаций, но я не знаю, что делать.

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

private List<String> internalData;

public List<String> getSomeList() {
    return Collections.unmodifiableList(internalData);
}

Ответ 5

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

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

Ответ 6

Я не думаю, что есть способ сделать это в Java для не примитивных объектов (вы всегда передаете ссылки на такие объекты). Самое близкое, что вы могли бы сделать, это вернуть копию объекта (используя клон или что-то в этом роде); но это не было бы очень идиоматической Java.

Я хочу предоставить доступ только к "видимой" части объекта-члена, что вы можете сделать, это создать интерфейс с видимой частью и вернуть этот интерфейс. Например:

public interface Bar {
     public int getBing();
}

public class BarImpl implements Bar {
     private int bing;
     public int getBing() {
        return bing;
     }
     public void setBing(int bing) {
        this.bing = bing;
     }
}

public class Foo {
     private BarImpl bar;

     public Bar getNonModifiableBar() {
         return bar; // Caller won't be able to change the bing value, only read it.
     }
}

Ответ 7

Он возвращается к возвращенному объекту, чтобы предотвратить его модификацию. Java не предоставляет декларативную/компиляционную проверку немодифицируемых объектов, за исключением того, что в типе отсутствуют мутаторы.

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

Если вы действительно мотивированы, вы можете получить проверки времени компиляции, указав только интерфейсы (или классы) только для чтения, которые сами раскрывают/реализуют методы доступа. Имейте в виду, что просто объявление о том, что метод возвращает интерфейс только для чтения, не будет препятствовать модификации среды выполнения, если клиент использует интроспекцию, а объект предоставляет мутаторы (которые не вызывают UnsupportedOperationException).

Ответ 8

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

например. вместо

public List<String> getSomeList();

есть

public String getSomeElement(int index);

Ответ 9

Когда вы сделаете что-то вроде этого:

Object2 obj2 = obj1.getObj2();
obj2 = new Object2();

Исходный частный член (obj1.obj2) остается как бы прежде (просто чтобы убедиться, что вы поняли эту концепцию). Вы можете просто опустить setter в obj2, чтобы внутреннее поле не могло быть изменено.

Если вы хотите, чтобы поля Object2 неизменяемы, вам нужно будет применить один и тот же шаблон (частные поля, без сеттеров).

Ответ на ваш вопрос?