Soru tarihi:
Java, başından beri Serializable arayüzü aracılığıyla nesnelerin serileştirilmesi mekanizmasını desteklemektedir. Bazen bir nesnenin durumunu kaydetmek gerekir, ancak tüm alanların serileştirilmesi gerekmez — örneğin, güvenlik açısından hassas olabilirler veya dinamik olarak hesaplanıyor olabilirler. Bu tür durumlar için transient modifikatörü icat edilmiştir.
Sorun:
Bir nesneyi tamamen serileştirdiğinizde, belirli alanların özelliklerini göz önünde bulundurmazsanız, özel veya serileştirilmeye uygun olmayan verilerin sızmasına neden olabilirsiniz. Ayrıca, ağır veya geçici alanların (örneğin, bağlantılar, veritabanı bağlantısı) serileştirilmesi ve serileştirmeden çıkarılması hatalara veya performans düşüşüne neden olabilir.
Çözüm:
Nesneyi kaydederken serileştirilmemesi gereken alanlar için transient modifikatörünü kullanın. Bu alanlar, serileştirme mekanizması tarafından yok sayılır ve serileştirmeden sonra varsayılan değerlere (örneğin, referans tipleri için null veya sayılar için 0) sahip olurlar.
Örnek kod:
import java.io.*; class User implements Serializable { private String username; private transient String password; // Serileştirilmez! public User(String username, String password) { this.username = username; this.password = password; } }
Anahtar özellikler:
Statik bir alan transient olabilir mi?
Cevap: Bir alanı static transient olarak ilan edebilirsiniz, ancak bunun mantığı yoktur: statik alanlar zaten serileştirilmez, çünkü sınıfa değil nesneye aittir.
Transient alanlar üzerinde tam kontrol sağlanabilir mi?
Cevap: Evet, private void writeObject(ObjectOutputStream out) ve private void readObject(ObjectInputStream in) yöntemlerini gerçekleştirerek, gerekirse transient alanları kendiniz serileştirebilirsiniz.
Örnek kod:
private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); // out.writeObject(password); // transient alanı açıkça serileştirmek gerekirse }
Deserileştirmeden sonra final transient alanına ne olur?
Cevap: final transient alanlar da varsayılan değerleri (genellikle sıfır veya null) alır, ancak daha sonra özel hileler olmadan değiştirilemez, bu da sıklıkla hatalara neden olur.
DatabaseConnection ile transient olan bir nesneyi serileştirdik. Deserileştirmeden sonra bu bağlantının yöntemlerini çağırmaya çalıştık — NullPointerException aldık.
Artılar:
Eksiler:
Transient parolası olan User nesnesini serileştirdik, deserilşe ederken readObject içerisinde kullanıcıdan parolayı talep ettik veya bağlantıyı yeniden kurduk.
Artılar:
Eksiler: