Хороший способ возврата изменчивого объекта

Скажем, у меня есть комментарий класса, и у меня есть частное поле с именем commentDate, которое является java.util.Date и с геттером с именем getCommentDate.

Почему лучше вернуть копию этой даты (вернуть новую дату (commentDate.getTime())), чем просто вернуть эту дату...

Как пользователь может изменить состояние объекта этой Даты, поскольку это геттер, а не сеттер?

Ответ 1

Прежде всего, пожалуйста, пожалуйста избегайте использования геттеров и сеттеров как можно больше. Если у вас есть оба для одного поля, вы почти наверняка делаете что-то неправильно. Мне все равно, что говорят вам Java-гуру. Они не знают, о чем они говорят. Это не работает OO. OO не является проектным проектом, чтобы превращать обращения с полями в вызовы методов. Это фактически не инкапсулирует что-либо.

Тем не менее, если вы вернете дату, то вызывающий код имеет ссылку на ваш объект даты и может использовать свой полный интерфейс. Поскольку даты являются изменяемыми объектами, интерфейс включает в себя вещи, которые могут изменять состояние объекта. Поскольку ссылка на вашу дату, ваше состояние даты будет изменено. Не имеет значения, как код вызова получил дату (т.е. "С геттером" ).

Ответ 2

Так как java.util.Date реализует Cloneable, вы можете легко клонировать дату, например:

public class DateTest {
    private Date date;

    public DateTest() {

    }

    public Date getDate() {
        return (Date) date.clone();
    }

    public void setDate(Date date) {
        this.date = (Date) date.clone();
    }       
}

Ответ 3

Как пользователь может изменить состояние объекта этой даты, поскольку это геттер, а не сеттер?

Легко:

Comment comment = new Comment();
comment.getCommentDate().setTime(0); // now it January 1, 1970 00:00:00 GMT.

Ответ 4

Пользователь не может "заменить" экземпляр, предоставленный getCommentDate(). Тем не менее, пользователь может вызвать getCommentDate(). SetMonth (10) и тем самым изменить дату. Таким образом, если это вызывает беспокойство, я бы посоветовал вам вернуть копию "оригинального" экземпляра.

Ответ 5

Так как java.util.Date является изменяемым, его можно изменить с помощью получателя следующим образом:

getCommentDate().setYear(2011)

Это приведет к тому, что commentDate в комментарии будет изменен на 2011 год. Все остальные методы набора на Date можно вызывать так же хорошо, как пример.

Ответ 6

Следуйте примеру Tapas Bose, мы можем использовать JAVA 8 для обработки случаев NULL:

public class DateTest {
private Date date;

public DateTest() {

}

public Date getDate() {
    return Optional.ofNullable(date).map(Date::getTime).map(Date::new).orElse(null);
}

public void setDate(Date inputDate) {
    this.date= Optional.ofNullable(inputDate).map(Date::getTime).map(Date::new).orElse(null);
}}

Ссылка: Есть ли способ скопировать объект Date в другую дату Объект без использования ссылки? (Ответ Николаса Хеннео)

Ответ 7

В Java вы имеете дело со ссылками. Когда вы получаете getter и возвращаете свой commentDate, вы фактически возвращаете ссылку на объект. Это означает, что это тот же объект, как в вашем приватном поле, вызывающий может работать из-за ссылки, возвращаемой getter.