Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Значимые и ссылочные типы. Семантика присваивания






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

Типы данных можно разделить на значимые и ссылочные. Для значимых типов, называемых также развернутыми, значение переменной (объекта) является неотъемлемой собственностью переменной (точнее, собственностью является память, отводимая значению, само значение может изменяться). Значимый тип принято называть развернутым, подчеркивая тем самым, что значение объекта развернуто непосредственно в памяти, отводимой объекту.

Для ссылочных типов значением служит ссылка на некоторый объект в памяти, расположенный обычно в динамической памяти - " куче". Объект, на который указывает ссылка, может быть разделяемым. Это означает, что несколько ссылочных переменных могут указывать на один и тот же объект и разделять его значения.

Будем называть целью левую часть оператора присваивания, а источником - правую часть оператора присваивания. Источник и цель могут быть как значимого, так и ссылочного типа. Присваивание будем называть ссылочным, если цель ссылочного типа. В этом случае источник должен быть ссылочного типа или быть приведенным к этому типу. Присваивание будем называть значимым, если цель значимого типа. В этом случае источник должен быть значимого типа или быть приведенным к этому типу.

Цель и источник значимого типа. Здесь наличествует семантика значимого присваивания. В этом случае источник и цель имеют собственную память для хранения значений. Если типы цели и источника совпадают, то никаких проблем нет. Значения источника копируются и заменяют значения соответствующих полей цели. Источник и цель после этого продолжают жить независимо. У них своя память, хранящая после присваивания одинаковые значения. Если типы разные, то необходимо преобразование типов. Оно может быть безопасным и тогда выполняется автоматически. В противном случае оно должно явно задаваться программистом.

Цель и источник ссылочного типа. Здесь имеет место семантика ссылочного присваивания - присваивание ссылок. В этом случае значениями источника и цели являются ссылки на объекты, хранящиеся в динамической памяти (" куче"). Если типы источника и цели совпадают, то никаких проблем нет. Цель разрывает связь с тем объектом, на который она ссылалась до присваивания, и становится ссылкой на объект, связанный с источником. Результат ссылочного присваивания двоякий. Объект, на который ссылалась цель, теряет одну из своих ссылок и может стать " висячим" - бесполезным объектом, на который никто не ссылается, так что его дальнейшую судьбу определит сборщик мусора.

После присваивания с объектом в памяти, на который ссылался источник, теперь связываются, по меньшей мере, две ссылки, рассматриваемые как различные имена одного объекта. Ссылочное присваивание приводит к созданию псевдонимов - к появлению разных имен у одного объекта. Особо следует учитывать ситуацию, когда цель и/или источник имеет значение null - нулевой ссылки, не указывающей ни на какой объект. Если такое значение имеет источник, то в результате присваивания цель получает это значение и более не ссылается ни на какой объект. Если же цель имела значение null, а источник - нет, то в результате присваивания ранее " висячая" цель становится ссылкой на объект, связанный с источником.

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

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

Цель ссылочного типа, источник значимого типа. В этом случае " на лету" значимый тип преобразуется в ссылочный. Как обеспечивается двойственность существования значимого и ссылочного типа - переменной и объекта? Ответ прост: за счет эффективно реализованной операции " упаковать" (boxing), выполняемой автоматически.

Такое присваивание возможно лишь в том случае, когда цель принадлежит классу object. Поскольку класс object является родителем для всех классов, в том числе и для значимых классов, при таком присваивании никаких ошибок возникать не будет, оно всегда возможно.

Цель значимого типа, источник ссылочного типа. В этом случае " на лету" ссылочный тип преобразуется в значимый. Операция " распаковать" (unboxing) выполняет обратную операцию - она " сдирает" объектную упаковку и извлекает хранимое значение. Заметьте, операция " распаковать" не является обратной к операции " упаковать" в строгом смысле этого слова. Оператор object obj = x корректен, но выполняемый следом оператор x = obj приведет к ошибке. Недостаточно, чтобы хранимое значение в упакованном объекте точно совпадало по типу с переменной, которой присваивается объект. Необходимо явно заданное преобразование к нужному типу.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.