2016-04-25 3 views
1

Как я понял из того, что я прочитал, в принципе есть два способа создания совершенно новых объектов в Java: 1) с помощью оператора new и 2) с помощью сериализации (для глубокого копирования, например). Все другие манипуляции с объектами (например, присваивание, например) касаются ссылок на существующие объекты. Но в чем разница между двумя вышеупомянутыми способами с точки зрения внутренней логики? Похоже, что одно отличие состоит в том, что сериализация каким-то образом не использует методы-конструкторы. Я прав? Существуют ли другие различия?Новые объекты: новый оператор и сериализация

«Внутренняя логика» Я имею в виду, как компилятор (или тот, кто имеет дело с ним) создает объект поэтапно, какой алгоритм он использует, какие методы используются для этого и т. Д. Больше похоже на то, о чем писала Маргарет Блум в своем ответе, но более подробно.

ДАЛЕЕ CONFUSION ПОЯСНЕНИЯ:

Так что я получаю это правильно, что во время десериализации копию объекта:

class Class1 { 
    static ARRAY_LENGTH = 10; 
    public class1() { 
     int[] anArray = new int[ARRAY_LENGTH]; 
     anArray[0] = 5; 
     ... 
     anArray[9] = -2; 
    } 
} 

будет включать в себя копию массива, созданного elsehow (как? поскольку конструктор не был вызван)? И, кроме того, хотя исходный массив (до сериализации) был создан с использованием поля static (который потерян во время сериализации), его десериализованная копия будет, тем не менее, идентична исходному массиву?

+0

Ну, есть 'clone()' тоже. – markspace

+0

И несколько методов в JNI. – EJP

+0

Вы должны сами написать «внутреннюю логику» конструкторов и код сериализации.Поэтому ответ на ваш вопрос: «Какую бы разницу вы ни делали». Или вы имели в виду что-то еще? – Raedwald

ответ

3

Операция сериализации и оператор new - это совершенно разные вещи, хотя они оба приводят к ссылке на вновь выделенный объект.

Вы можете найти подробную информацию об операторе new в главе 15.9.4 Run-Time Оценка класса Instance Создание выражений в Java Language Specification.

Во время выполнения оценка выражения создания экземпляра класса выглядит следующим образом.
[...]
Далее, пространство выделено для экземпляра нового класса.
[...] Новый объект содержит новые экземпляры всех полей, объявленных в указанном классе класса и всех его суперклассах.
[...] Далее, фактические аргументы конструктора оцениваются слева направо. [...]
Затем вызывается выбранный конструктор указанного типа класса. В результате получается , вызывающий по крайней мере один конструктор для каждого суперкласса типа класса.
Значение выражения создания экземпляра класса: ссылка на вновь созданный объект указанного класса.Каждый раз, когда выражение оценивается, создается новый объект .

Редактирование шахты
Так Короче говоря, new выделяет пространство для нового объекта (в частности, пространства для ее полей), инициализирует его поля со значениями по умолчанию и вызывает выбранный конструктор.


Java Serialization - другое дело полностью.

Возможность хранения и извлечения объектов JavaTM имеет важное значение для создания всех, кроме самых преходящих приложений. Ключ к хранению и извлечению объектов в сериализованной форме представляет состояние объектов, достаточное для восстановления объекта (ов). Упор шахта

Это означает, что сериализации был разработан, чтобы позволить программисту сохранить объекты состояния в упорной среде (абстрагируются в поток в Java) и read them back.

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

Чтение объекта из объекта ObjectInputStream аналогично созданию нового объекта. Так же, как конструкторы нового объекта вызывается в порядке от суперкласса к подклассу, объект, который считывается из потока, десериализуется из суперкласса в подкласс. Метод readObject или readObjectNoData вызывается вместо конструктора для каждого подкласса Serializable во время десериализации.

Упор шахта


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

Несмотря на то, что их можно считать похожими для их окончательного результата, вы должны иметь в своем сознании действительно четкое различие между двумя.

+0

Да, это разные вещи, но я бы не согласился с тем, что они не связаны. На самом деле часто жизненно важно видеть эти две стороны одной и той же монеты. (Например, когда вы устанавливаете инварианты класса.) – biziclop

+0

Обычно понятно, что они «совершенно разные» в Java. Например, в * Эффективном Java * Джошуа Блох указывает, что сериализация является экстралингвистической. Сериализация не задана спецификацией языка, она указана API. Я вижу, что вы говорите, но общепринятый ответ экспертов Java заключается в том, что они намного отличаются друг от друга. – markspace

0

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

Если объект реализует java.io.Serializable, он будет помечен как Serializable Object, а данные в объекте могут быть преобразованы в поток байтов (serialize), и мы могли бы использовать данные этого байтового потока для создания нового объекта в памяти (desrialize). Java поддерживает 2 объекта для сериализации и десериализации, это ObjectInputStream и ObjectOutputStream

0

Не согласен с deserializiation does not invoke constructors:
На самом деле, Deserializiation просто не вызывает конструкторы, определенные в теле класса. В зависимости от java.reflect, конечно, необходимо вызвать конструкторы для получения Object от Class. Он просто вызывает пользовательские конструкторы, созданные sun.reflect.ReflectionFactory.newConstructorForSerialization(Class<?> var1, Constructor var2).

Смежные вопросы