Как я могу сделать класс неизменным, если у него есть переменная экземпляра java.lang.Object? - PullRequest
4 голосов
/ 19 августа 2011
final public class ImmutableWithObject {

    final Object obj;
    final List myList;

    ImmutableWithObject(Object obj1, List list)
    {
        this.obj = obj1;
        this.myList = ((List) ((ArrayList) list).clone());
    }

    public Object getObj() {
        return this.obj;
    }

    public List getMyList() {
        return (List) ((ArrayList<String>) this.myList).clone();
    }

    public static void main(String[] args) {

        ImmutableWithObject io = new ImmutableWithObject(new Date(), new ArrayList());

        ((Date) io.getObj()).setDate(22);

        System.out.println((Date) io.getObj());
    }
}
o/p : Mon Aug 22 00:50:04 IST 2011

что неверно.

Ответы [ 4 ]

6 голосов
/ 19 августа 2011

Неизменяемый означает, что после создания объекта его состояние не меняется.

  • Сделать окончательный класс (что вы уже сделали)
  • Сделать переменные экземпляра частными и окончательными
  • Не предоставлять методы, которые изменяют состояние
  • При передаче переменных экземпляра отправляйте копии вместо оригинала.

Из EJ Item 15 <- <em>Там больше информации

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

2 голосов
/ 19 августа 2011

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

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

1 голос
/ 19 августа 2011

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

0 голосов
/ 19 августа 2011

Сделать переменные-члены private final и скопировать параметры:

final class ImmutableWithObject {

    private final Object obj;
    private final List myList;

    public ImmutableWithObject(Object obj1 , List list)
    {
       this.obj = obj1.clone();
       this.list = (List) list.clone();
    }
}

Это не позволит никакому другому классу изменять ваше внутреннее состояние и не позволит ImmutableWithobject изменить myList или objРекомендации. Однако состояние объекта и список могут по-прежнему управляться внутренне.Как отмечали другие, кто бы ни прошел мимо списка или obj1 вашего класса, он сможет манипулировать им и извне.Поскольку в C ++ нет эквивалента чего-то вроде const, нам придется копировать объекты, чтобы убедиться, что они не изменены извне.

Точно так же, если был геттер, он также должен возвращать только копию (или некоторый интерфейс только для чтения или оболочку только для чтения):

 public Object getObj() { return obj.clone(); }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...