Ключевое слово transient используется в Java для обозначения полей класса, которые должны быть исключены из процесса сериализации – то есть, эти поля не будут сохранены при сохранении объекта в поток байтов.
Это полезно, когда:
Пример использования:
import java.io.*; class User implements Serializable { private String username; private transient String password; // не будет сериализовано public User(String username, String password) { this.username = username; this.password = password; } }
После десериализации поля password будет иметь значение null.
Что произойдет, если transient-поле является ссылкой на объект, который сам реализует Serializable?
Ответ: Поле все равно не сериализуется – это относится к полю, а не к типу объекта. Даже если объект реализует Serializable, если поле отмечено transient, оно не погибнет в сериализации того объекта, где оно transient.
Пример:
class Credentials implements Serializable { String password; } class Account implements Serializable { transient Credentials credentials; }
Поле credentials всегда будет null после десериализации, даже если сама Credentials сериализуема.
История
В интернет-банке при проектировании объекта "Сессия пользователя" забыли объявить поле сессии авторизации transient, из-за чего сериализованные объекты логировались вместе с конфиденциальной информацией в файл. Это привело к утечке персональных данных.
История
В брокерском сервисе некоторые поля кэша были сериализованы по умолчанию. После восстановления из сериализованного состояния приложение начало использовать устаревшие данные из кэша, что привело к расхождению между реальными и отображаемыми суммами на счетах.
История
Разработчик реализовал transient-поле, предполагая, что значение будет автоматически заполнено после десериализации. Он не реализовал custom скорее-структуру (readObject/writeObject), в итоге поле оставалось null – программа аварийно завершалась при первом доступе к этому полю.