Класс, который вы на самом деле вызываете, не является классом Bar, а вместо этого классом Foo. То, что вы делаете в foo_vector [0] = bar;
, - это вызов неявного оператора =, который делает все возможное, чтобы сделать что-то умное. Объем памяти по-прежнему является размером с Foo, поэтому он никогда не может быть баром.
Ключевое слово transient
в Java используется для указания того, что поле не должно быть частью сериализации (что означает сохранение, как в файл )
Из спецификации языка Java , Java SE 7 Edition , , раздел 8.3.1.3. переходный
Поля :
Переменные могут быть помечены
переходными
в указывают, что они не являются частью постоянное состояние объекта.
Например, у вас могут быть поля, производные от других полей, и это следует делать только программно, а не сохранять состояние посредством сериализации.
Вот класс GalleryImage
, который содержит изображение и миниатюру, полученную из изображения:
class GalleryImage implements Serializable
{
private Image image;
private transient Image thumbnailImage;
private void generateThumbnail()
{
// Generate thumbnail.
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
generateThumbnail();
}
}
В этом примере thumbnailImage
является миниатюрным изображением, которое создается путем вызова generateThumbnail
метод.
Поле thumbnailImage
помечено как transient
, поэтому сериализуется только исходное изображение
, а не сохраняется как исходное изображение и эскиз. Это означает, что для сохранения сериализованного объекта потребуется меньше памяти. (Конечно, это может быть или нежелательно в зависимости от требований системы - это всего лишь пример.)
Во время десериализации вызывается метод readObject
для выполнения любых операций, необходимых для восстановления состояние объекта обратно в состояние, в котором произошла сериализация. Здесь необходимо сгенерировать эскиз, поэтому метод readObject
переопределяется, так что эскиз будет сгенерирован путем вызова метода generateThumbnail
.
Для получения дополнительной информации см. ] Откройте для себя секреты статьи Java Serialization API (которая изначально была доступна в Sun Developer Network) имеет раздел, в котором обсуждается использование и представлен сценарий, в котором ключевое слово transient
используется для предотвращения сериализация определенных полей.
Во время десериализации вызывается метод readObject
для выполнения любых операций, необходимых для восстановления состояния объекта до состояния, в котором произошла сериализация. Здесь необходимо сгенерировать эскиз, поэтому метод readObject
переопределяется, так что эскиз будет сгенерирован путем вызова метода generateThumbnail
.
Для получения дополнительной информации см. ] Откройте для себя секреты статьи Java Serialization API (которая изначально была доступна в Sun Developer Network) имеет раздел, в котором обсуждается использование и представлен сценарий, в котором ключевое слово transient
используется для предотвращения сериализация определенных полей.
Во время десериализации вызывается метод readObject
для выполнения любых операций, необходимых для восстановления состояния объекта до состояния, в котором произошла сериализация. Здесь необходимо сгенерировать эскиз, поэтому метод readObject
переопределяется, так что эскиз будет сгенерирован путем вызова метода generateThumbnail
.
Для получения дополнительной информации см. ] Откройте для себя секреты статьи Java Serialization API (которая изначально была доступна в Sun Developer Network) имеет раздел, в котором обсуждается использование и представлен сценарий, в котором ключевое слово transient
используется для предотвращения сериализация определенных полей.
readObject
вызывается для выполнения любых операций, необходимых для восстановления состояния объекта до состояния, в котором произошла сериализация. Здесь необходимо сгенерировать эскиз, поэтому метод readObject
переопределяется, так что эскиз будет сгенерирован путем вызова метода generateThumbnail
.
Для получения дополнительной информации см. ] Откройте для себя секреты статьи Java Serialization API (которая изначально была доступна в Sun Developer Network) имеет раздел, в котором обсуждается использование и представлен сценарий, в котором ключевое слово transient
используется для предотвращения сериализация определенных полей.
readObject
вызывается для выполнения любых операций, необходимых для восстановления состояния объекта до состояния, в котором произошла сериализация. Здесь необходимо сгенерировать эскиз, поэтому метод readObject
переопределяется, так что эскиз будет сгенерирован путем вызова метода generateThumbnail
.
Для получения дополнительной информации см. ] Откройте для себя секреты статьи Java Serialization API (которая изначально была доступна в Sun Developer Network) имеет раздел, в котором обсуждается использование и представлен сценарий, в котором ключевое слово transient
используется для предотвращения сериализация определенных полей.
Чтобы позволить вам определять переменные, которые вы не хотите сериализовать.
В объекте у вас может быть информация, которую вы не хотите сериализовать / сохранять (возможно, ссылка на родительский объект фабрики), или, возможно, нет смысла сериализовать. Пометка их как «переходных» означает, что механизм сериализации будет игнорировать эти поля.
переходная
переменная - это переменная, которая не может быть сериализована.
Один из примеров, когда это может быть полезно, - это переменные, которые имеют смысл только в контексте конкретного экземпляра объекта и становятся недействительными после сериализации и десериализации объекта. В этом случае полезно сделать эти переменные null
вместо этого, чтобы вы могли при необходимости повторно инициализировать их полезными данными.
Системы сериализации, отличные от родной Java, также могут использовать этот модификатор. Например, Hibernate не будет сохранять поля, отмеченные модификатором @Transient или transient . Terracotta также уважает этот модификатор.
Я считаю, что образное значение модификатора таково: «это поле предназначено только для использования в памяти. Не сохраняйте и не перемещайте его за пределы этой конкретной виртуальной машины каким-либо образом. Его непереносимость ". т.е. вы не можете полагаться на его значение в другом пространстве памяти ВМ. Подобно volatile означает, что вы не можете полагаться на определенную семантику памяти и потоков.
Поскольку не все переменные имеют сериализуемую природу
Это необходим, когда вы не хотите делиться некоторыми конфиденциальными данными, связанными с сериализацией.
transient
используется, чтобы указать, что поле класса не нужно сериализовать.
Вероятно, лучшим примером является поле Thread
. Обычно нет причин для сериализации потока
, поскольку его состояние очень «зависит от потока».