Прежде всего, сеттеры и геттеры являются признаком плохого ОО. Обычно идея ОО состоит в том, что вы просите объект сделать что-то для вас. Установка и получение противоположны. Sun должна была придумать другой способ реализации Java-бинов, чтобы люди не воспринимали этот шаблон и думали, что он «правильный».
Во-вторых, каждый ваш объект должен быть миром сам по себе - обычно, если вы собираетесь использовать сеттеры и геттеры, они должны возвращать довольно безопасные независимые объекты. Эти объекты могут быть или не быть неизменными, потому что они просто первоклассные объекты. Другая возможность состоит в том, что они возвращают нативные типы, которые всегда неизменны. Поэтому высказывание «Должны ли установщики и получатели возвращать что-то неизменное» не имеет особого смысла.
Что касается создания самих неизменяемых объектов, вы должны фактически всегда делать члены внутри вашего объекта окончательными, если у вас нет веских оснований этого не делать (в качестве окончательного варианта должно было быть указано значение по умолчанию, слово «изменяемый» должно быть ключевым словом, которое заменяет это значение по умолчанию). Это означает, что везде, где это возможно, объекты будут неизменными.
Что касается предопределенных квазиобъектных вещей, которые вы можете обойти, я рекомендую вам обернуть вещи, такие как коллекции и группы значений, которые собираются вместе в свои собственные классы с помощью своих собственных методов. Я практически никогда не передаю незащищенную коллекцию просто потому, что вы не даете никаких советов или помощи по ее использованию, если использование хорошо спроектированного объекта должно быть очевидным. Безопасность также является фактором, поскольку предоставление кому-либо доступа к коллекции внутри вашего класса делает практически невозможным обеспечение того, чтобы класс всегда был действительным.