Принципиальным недостатком системы типов Java / .net является то, что у него нет декларативных средств для определения того, как состояние объекта связано с содержимым его полей ссылочного типа, а также для указания того, какому методу разрешено сохранять ссылочные значения. параметры типа. Хотя в некотором смысле для среды выполнения хорошо иметь возможность использовать поле Foo
одного типа ICollection<integer>
для обозначения множества разных вещей, система типов не может обеспечить реальную поддержку таких вещей, как неизменяемость, проверка эквивалентности, клонирование или любые другие подобные функции, не зная, представляет ли Foo
:
- Ссылка только для чтения на коллекцию, которая никогда не будет мутировать; класс может свободно делиться такой ссылкой с внешним кодом, не затрагивая его семантику. Ссылка инкапсулирует только неизменное состояние и, скорее всего, не инкапсулирует идентичность.
- Доступная для записи ссылка на коллекцию, тип которой является изменчивым, но который ничего не изменяет; класс может делиться такими ссылками только с кодом, которому можно доверять, чтобы не изменять его. Как указано выше, ссылка инкапсулирует только неизменное состояние и, вероятно, не инкапсулирует идентичность.
- Единственная ссылка во вселенной на коллекцию, которую она мутирует. Ссылка инкапсулирует изменяемое состояние, но не инкапсулирует идентичность (замена коллекции на другую, содержащую те же элементы, не изменит состояния включающего объекта).
- Ссылка на коллекцию, которую она мутирует, и чье содержимое она считает своей собственной, но к которой внешний код содержит ссылки, которые, как она ожидает, будут присоединены к текущему состоянию `Foo`. Ссылка будет инкапсулировать как идентичность, так и изменяемое состояние.
- Ссылка на изменчивую коллекцию, принадлежащую некоторому другому объекту, которую он ожидает присоединить к состоянию этого другого объекта (например, если объект, содержащий `Foo`, должен отображать содержимое некоторой другой коллекции). Эта ссылка инкапсулирует идентичность, но не инкапсулирует изменяемое состояние.
Предположим, что кто-то хочет скопировать состояние объекта, содержащего Foo
, в новый отдельный объект. Если Foo
представляет # 1 или # 2, в новом объекте можно сохранить либо копию ссылки в Foo
, либо ссылку на новый объект, содержащий те же данные; копирование ссылки будет быстрее, но обе операции будут правильными. Если Foo
представляет # 3, правильная отделенная копия должна содержать ссылку на новый отделенный объект, состояние которого копируется из оригинала. Если Foo
представляет # 5, правильная отдельная копия должна содержать копию исходной ссылки - она должна НЕ содержать ссылку на новый отдельный объект. И если Foo
представляет # 4, состояние объекта, содержащего его, не может быть скопировано изолированно; может быть возможно скопировать группу взаимосвязанных объектов, чтобы получить новую группу, состояние которой эквивалентно оригиналу, но было бы невозможно скопировать состояние объектов по отдельности.
Хотя система типов не сможет декларативно указать все возможные отношения, которые могут существовать между объектами, и что следует с ними делать, система и структура типов должны иметь возможность правильно генерировать код для производить семантически правильные тесты эквивалентности, методы клонирования, гладко взаимодействующие изменяемые, неизменяемые и «читаемые» типы и т. д. в большинстве случаев, если известно, какие поля инкапсулируют идентичность, изменяемое состояние, оба или ни одного. Кроме того, должна быть возможность для каркаса минимизировать защитное копирование и перенос в обстоятельствах, когда она может гарантировать, что переданные ссылки не будут переданы чему-либо, что может их изменить.