В чем разница между «экземпляром» и «инициализацией»?


105

Я слышал, как эти два слова используются в руководствах Microsoft по VB.NET. В чем разница между этими двумя словами, когда они используются в отношении переменных?

Ответы:


142

Значение по отношению к ссылочным типам

Переменные в C # находятся в одной из двух групп. Типы значений или ссылочные типы. Такие типы, как intи DateTimeявляются типами значений . Напротив, любой создаваемый вами класс является ссылочным типом. Строки C # также являются ссылочным типом. Большинство вещей в .NET framework являются ссылочными типами.

Части переменной

Есть имя переменной и ее значение . Две части .

В переменном имени является то , что вы объявить , что это будет. Значение является то , что вы назначить на него.

Переменные инициализируются

Все переменные всегда получают начальное значение в момент объявления переменной . Таким образом инициализируются все переменные .

Для типов значений , например, intкомпилятор предоставит им допустимое значение, если вы не сделаете этого явно. int«s инициализировать до нуля по умолчанию, DateTime» s инициализации для DateTime.MinValueпо умолчанию.

Переменные ссылочного типа инициализируются для объекта, который вы им передаете. Если вы этого не сделаете, компилятор не назначит объект (т.е. допустимое значение). В данном случае значение null- ничего. Итак, мы говорим, что ссылка инициализируется нулевым значением.

Объекты создаются

Люди рождаются. Объекты создаются. Младенец - это экземпляр Человека, объект - это экземпляр некоторого Класса.

Акт создания экземпляра класса называется инстанциацией (Ta-Da!)

Итак, объявите , инициализируйте и создайте экземпляр, как это

MyClass myClassyReference = new MyClass();

Выше неправильно говорить «... создание экземпляра объекта ...»


edit - вдохновлено обсуждением комментариев

Происходят три разные вещи (см. Выше) с использованием различной терминологии, и эта терминология не является взаимозаменяемой:

  1. Объявляется ссылочная переменная - MyClass myClassyReference
  2. Создается экземпляр объекта ( подразумевается ... из / данного класса ) -new MyClass()
  3. Объект присваивается переменной. =.

Повторяя факты:

  1. Переменная ссылочного типа также называется просто «ссылкой». «Переменная типа значения» не является ссылкой.

  2. Это: «objectA - это экземпляр объекта» в корне неверно. Если objectA был «экземпляром objectB», то должно быть, что objectA начинает жизнь с типом objectB - каким бы он ни был - и текущим состоянием - чем бы он ни был. Как насчет создания объектов D, E и F при изменении объекта B? Нет, нет! Это концептуальный и технический случай, когда «objectA является экземпляром класса». «Создание» и «экземпляр» имеют точное значение - объект получает свой тип, определения и значения из класса.

  3. MyClass myClassyReference = null Обычно мы не говорим «переменной присвоено значение NULL» и никогда не говорим «переменная ссылается на NULL». Нет. Вместо этого мы говорим «переменная имеет значение NULL»; или «переменная ни на что не ссылается», или «ссылка пуста»

Практическое применение:

  • Я нажимаю пальцем на ваш код и говорю: «У этого экземпляра недопустимое свойство. Может быть, поэтому цикл не работает. Вы должны проверить параметры во время создания экземпляра». (т.е. аргументы конструктора).

  • Я вижу это в вашем коде,

    MyClass myClassyReference;
    myClassyReference.DoSomething();

    «Вы объявили переменную, но не присвоили ее. Она пуста, поэтому ни на что не ссылается. Вот почему вызов метода вызывает исключение».

конец править


Невыносимая легкость существования

A типа базового имя и значение переменного существуют независимо. И я имею в виду независимый.

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

Экземпляр объекта может быть много ссылок на него.

Объявлено ссылка может или не может быть направлен на объект.


Прекрасное объяснение!
М. Фавад Сурош

Если неправильно сказать: «... создание экземпляра объекта ...», что вы должны сказать? "... создание экземпляра объекта и присвоение ему ссылки ..."?
Аарон

Или как насчет: «... создание экземпляра объекта и инициализация переменной ссылкой на него»? Это включает в себя оба слова и, кажется, все объясняет, хотя и довольно долго. Что вы думаете?
Аарон

... что ты должен сказать? Скажите: «создание экземпляра класса», а не «... объекта». И «создание экземпляра переменной для ссылки на нее» - это двусмысленный разговор, и это неверно по двум причинам: (1) создаются только объекты. (2) Переменная, «указывающая на» объект, является ссылочной переменной, или, короче говоря, переменная является ссылкой. Я скажу иначе: переменная «ссылочного типа» - это ссылка. Он относится к объекту или указывает на него.
radarbob

40

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

Например, вот переменная:

Dim obj as Object

Эта переменная не была инициализирована . Как только я присвою значение objпеременной, она будет инициализирована. Вот примеры инициализации:

obj = 1
obj = "foo"

Создание экземпляра - это совсем другое дело, но оно связано, поскольку создание экземпляра обычно сопровождается инициализацией:

Dim obj As New Object()

В предыдущей строке кода, то objпеременная инициализируется со ссылкой на новый , Objectкоторый был экземпляр . Мы говорим, что новый Objectэкземпляр был создан, потому что мы создали его новый экземпляр.

Теперь я считаю, что VB.NET делает это намного более запутанным, чем C #, потому что неясно, происходит ли присвоение в приведенном выше коде. В C # гораздо яснее, что существует как создание экземпляра, так и инициализация переменной:

Object obj = new Object();

@Andrew объект obj = 1; - это инициализация, а объект obj = new object () / - создание экземпляра, а инициализация - это то, что вы упомянули. Теперь я хочу спросить вас о двух вещах. 1. что это? объект obj; ? 2. была ли выделена память, когда я использую объект obj; ?? или он размещается, когда я инициализирую его этим объектом кода obj = 1; ?
kashif 02

Я бы сказал, что «объект obj» - это объявление, и нет, память еще не выделена. Или, по крайней мере, достаточно памяти, чтобы хранить значение "null". Фактическая память для переменной будет выделена на основе значения после ее инициализации.
Аарон

14

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

Часто это более или менее одно и то же. Это:

SqlConnection conn = new SqlConnection();

инстанцирует на SqlConnectionобъект и инициализирует на connпеременную, установив его в этом случае.

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


4

* Создание означает создание экземпляра для класса или объекта. Инициализация означает * инициирование того же объекта или класса для любой цели. **


3

Instantiated означает, что экземпляр объекта был создан. Инициировано означает, что тот же объект выполнил некоторую инициализацию.


2

Когда вы создаете экземпляр класса или объекта, вы создаете его новый экземпляр или выделяете память для его «хранения». Инициализация этого объекта будет инструкциями, которые выполняются во время создания экземпляра.


2

Создание экземпляра - это создание экземпляра класса. Тогда этот экземпляр является объектом, и вы можете установить его свойства или вызвать для него методы (указать ему что-то делать).

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

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

Разница в том, что создание экземпляра - это создание вещи, которая может что-то делать; инициация - это то, что делается.


1

См. Документы по Java: https://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html

" Point originOne = новая точка (23, 94);

Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object."

1

Мы можем видеть это так. Для строки кода ниже:

var p = new Person();

Вышеупомянутую строку можно прочитать двумя способами:

  1. Переменная p была инициализирована как класс человека
  2. Класс Person создан в переменной p

Тема ссылки или контекст имеет значение. Говоря о переменных , мы используем слово инициализировать . Говоря о классе / типе , мы используем слово instantiate .


0

Создание относится к выделению памяти для создания экземпляра класса, тогда как инициализация относится к именованию этого экземпляра путем присвоения имени переменной этому экземпляру.

Например: SqlConnection conn = new SqlConnection();

Вот newключевое слово, которое выделяет память для экземпляра и connявляется именем переменной, присвоенным этому экземпляру.


0

Другие объяснили разницу, поэтому я не буду вдаваться в подробности. Но бывают случаи, когда при создании экземпляра объект не инициализируется должным образом. Когда вы создаете экземпляр объекта, вы также инициализируете его некоторыми данными. Класс / тип будет иметь логику инициализации, тогда как логика создания экземпляра обычно выполняется с помощью newключевого слова (в основном выделение памяти, копирование ссылок и т. Д.). Но создание экземпляра не обязательно должно приводить к действительному состоянию для объектов, когда мы можем сказать, что объект не инициализирован . Вот практический пример, когда объект может быть создан, но не инициализирован (извините, например, в C #).

class P { string name = "Ralf"; }

WriteLine(new P().name); // "Ralf";
WriteLine((FormatterServices.GetUninitializedObject(typeof(P)) as P).name); // null

GetUninitializedObject не вызывает конструктор для создания экземпляра объекта там (но некоторая внутренняя магия).

Можно также утверждать, что типы значений не создаются, а только инициализируются, поскольку при этом не требуется новое распределение, new..но это зависит от определения создания экземпляра.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.