Konu tarihi
Java'nın ilk gününden itibaren, uygulama oturumları arasında nesneleri kaydetme ihtiyacı ortaya çıktı — bunları ağ üzerinden iletme, bir veritabanına veya diske yazma. Bu amaçla, nesneleri bayt akışına ve geri dönüştürmeye (seri hale getirme ve tersine seri hale getirme) olanak tanıyan Serializable arayüzü icat edilmiştir.
Sorun
Eğer bir sınıf Serializable arayüzünü gerçekleştirmiyorsa, onun bir örneğini seri hale getirmeye çalışmak bir istisna fırlatacaktır. Dahası, seri hale getirme sadece alanların değerlerini değil, aynı zamanda durumlarını da kaydeder; bu nedenle hatalı bir uygulama beklenmedik zayıflıklara, nesnenin geri yüklenmesi hatalarına veya hatta veri kaybına yol açabilir.
Çözüm
Serializable arayüzü işaretçi (marker) bir arayüzdür, yani herhangi bir yöntem içermez. Doğru bir seri hale getirme için serialVersionUID değerini açıkça belirtmek ve seri hale getirilmemesi gereken alanlar için transient anahtar kelimesini kullanmak önemlidir.
Kod örneği:
import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; private String username; private transient String password; // seri hale getirilmeyecek public User(String username, String password) { this.username = username; this.password = password; } }
Ana özellikler:
transient kullanımı, belirli alanların seri hale getirilmesini engelliyorserialVersionUID alanını açıkça belirtmek zorunlu mu?
Hayır, zorunlu değil, ancak belirtilmezse otomatik olarak oluşturulacaktır. Ancak sınıfta değişiklikler yapıldığında, eski seri hale getirilmiş versiyonun geri yüklenmesi InvalidClassException ile sonuçlanabilir. Bu nedenle, bu alanı her zaman açıkça belirtmek daha iyidir.
Statik alanlar seri hale getirilir mi?
Hayır, yalnızca statik olmayan (instance) alanlar seri hale getirilir. Statik alanlar sınıfa ait olup, dolayısıyla seri hale getirme ve tersine seri hale getirme sırasında değerleri kaydedilmez ve geri yüklenmez.
Serializable uygulamayan alanlara sahip bir nesne seri hale getirilebilir mi?
Hayır, eğer en az bir statik olmayan alan seri hale getirilemiyorsa ve transient olarak belirtilmemişse, seri hale getirmeye çalışmak NotSerializableException istisnasına yol açar.
serialVersionUID belirtilmemesi ve bunun sonucunda nesne versiyonları arasında uyumsuzluktransient olmadan hassas verilerin (örneğin, şifrelerin) seri hale getirilmesiKullanıcıları önbelleğe alan bir uygulamada serialVersionUID belirtilmedi ve kodun geliştirilmesi sırasında User sınıfının yapısı değiştirildi. Uygulama başlatıldığında InvalidClassException hatası meydana geldi ve tüm seri hale getirilmiş veriler kayboldu.
Artılar:
Eksiler:
Benzer bir projede her zaman serialVersionUID açıkça belirtilmiş ve seri hale getirilmeyecek tüm alanlar transient olarak tanımlanmıştı. Bu sayede, yapı değişikliği sonrası seri hale getirilmiş nesneler başarılı bir şekilde yüklendi.
Artılar:
Eksiler: