Java Serialization

JAVA’DA SERIALIZATIONNot: Arkadaşlar konu, orta ve ileri düzey bilgiler gerektirmektedir.Bu ders, Javanın uzun zaman önceki sürümlerinde bile var olan bir özellikle alâkalı olacak. Java’da Serializable interface’ini kullanan her nesne, bir byte dizisi olarak saklanabilir. Daha sonra tekrar eski haline geri getirilebilir. Bu işlem, Java’da yazılan diğer çoğu kod gibi, Platformdan bağımsızdır. Yani siz bir nesneyi Windows kullanan bir bilgisayarda “Serialize” ettiniz. Bunu Linux işletim sistemini kullanan bir bilgisayarda bile geri getirebilirsiniz. Arada yapılacak işlemler, sizin probleminiz değildir. Onları Java VM sizin yerinize halleder.
Serialization işlemi, bir objenin bir hafızaya, buffer’a veya bir network bağlantısına kaydedilmesidir denilebilir. Java VM, objeleri birer byte dizisi haline getirir ve bunları dosyalar.

Şimdi teknik olarak bu işlemin nasıl yapıldığını olabildiğince basit bir şekilde, birkaç örnekle anlatmaya çalışalım.

Not: Bir objeyi bir dosyaya serialize ederken, javadaki gelenek, dosyala .ser uzantısı vermektir.

Yukarıdaki class, Serialize edeceğimiz, olayı anlayıp kullanışlılığını analiz edebileceğimiz bir classtır. İçinde, gün ve saati tutan bu class, serialize2 classı içinde kullanılarak dosyaya saklanacak ve sonra da deserialize2 classı içinde tekrar açılacaktır. Bu yapılırken, siz de aradan geçen zamanı görebileceksiniz. Hatta isterseniz, benim upload edeceğim kod dosyaları arasındaki “zaman.ser” dosyasını alıp, deserialize2 classını yeniden çalıştırarak, canlı canlı bu olaya şahit olabilirsiniz. Ben linux işletim sistemiyle serialize ettim. Siz de windows’unuzda deneyip, platform bağımsızlığını kendi gözlerinizle görebilirsiniz.

Yukarıdaki class, serileştirme(serialization) işleminin yapıldığı classtır. FileOutputStream ve ObjectOutputStream, obje yazmak için gereken classlardır.

Yukarıdaki classımız da, yazmış olduğumuz objeyi tekrardan kullanabilmek için dirittiğimiz classtır. Comment’e dönüştürdüğüm kod parçası, karşılaşabileceğiniz exceptionlardır. Ben onlar için ayrıca bir işlem yapmayacağım. Bu yüzden tembellik yapıp komple Exception yakalayan bir catch bloğu yazdım. Duruma göre uygun olan uyarılar için bunları kullanmanız gerekebilir.
Son olarak da output dosyamız.

Gördüğünüz üzere, Serialize ettiğimiz objeyi, serialize ettiğimiz an olarak geri alıyoruz. Ne eksik ne fazla.
Bazı önemli noktalar:

try/catch bloğu ClassNotFoundException yakalamaya çalışır. Bu,readObject() metodu tarafından oluşturulur. Bir JVM’in bir objeyi deserialize edebilmesi için, bu class için bytecode dosyasını bulabilmesi lazım. Yani SuAn.class dosyası. Eğer JVM, deserialize ederken bu classı bulamazsa ClassNotFoundException fırlatır.
readObject() metodunun döndüğü değeri typecast ile SuAn referansına dönüştürüyoruz. Buna dikkat edin.

(Nonserializable Objects)
Son olarak bahsedilmesi gereken bazı noktalar var. Object classı, Serializable interface’ini implement etmez. Güzel Türkçemize çevirip ifade edersek, “Object sınıfı, Serializable arayüzünü uygulamaz. Yani Object sınıfının bazı alt sınıfları(bizim yazmadığımız ) serileştirilemez. İyi haber olarak şunu söyleyelim: AWT ve Swing parçalarının(componentlerinin) bile çoğu serileştirilebilir.
Diğer yandan, Thread, OutputStream ve Socket gibi classlar ve subclassları(alt sınıfları) serileştirilemezler. (Nonserializable). Cidden, zaten öyle olmaları da anlamlı olmazdı. Mesela Thread, benim JVM’imdeki thread, benim sistemimin hafızasını kullanır. Bunu serialize edip keni bilgisayarınızda çalıştırmaya çalışmak mantıksız olur.
Tekrar üstteki paragrafa dönelim. Object sınıfı Serializable değildir. Yani ona extend eden classlar, ayrıca belirtilmediyse Serializable olmaz. Bu da karşımıza bir problem çıkarır: Ya ben, classımda Serializable olmayan bir obje kullanıyorsam? Daha açık söylemek gerekirse, ya ben classımda Thread objesi kullanıyorsam? Ne olacak şimdi? Ben hala bu classın bir objesini dosyaya yazabilir miyim? Cevap: Evet, siz bu Thread objesini transient olarak tanıttığınız sürece, yazabilirsiniz.

Biz ne zaman KaliciAnim objesi oluşturursak, animator threadi bizim beklediğimiz gibi oluşturulacak ve çalışacaktır. Altıncı satırda transient diyerek, Serialization mekanizmasına, bu parçanın serileştirilmeyeceğini, kalan kısmın serileştirileceğini söylemiş oluyoruz. (bu durumda serileştirmeyi bekleyen sadece animSpeed var.) Yani siz, Serialize edilemeyen veya Serialize edilmesini istemediğiniz şeyleri transient olarak tanıtmalısınız.
Not: Serialization işleminde değişkenlerin private ya da public oluşuna bakılmaz. transient olmayan her obje, serialization işlemine tabidir.

Bunu daha iyi anlamak için ikinci bir örnek kod paylaşalım.



Output:

Açıklama yapılması gereken bir nokta var. SGN numarası neden 0 oldu? Çünkü biz onu transient olarak belirttik. Yani geçici dedik. Onu her bilgisayarda baştan oluşturacak, serialize ederken onu kaydetmeyecek dedik. Bu yüzden, bu objeyi dosyaya yazarken SGN’sini yazmadı. Haliyle okurken de SGN’sini okumadı.

Arkadaşlar konunun sonuna gelmedik henüz. Sizin şu anda kafanızda birkaç soru oluşmuş olması lazım. (Olmasa bile) Hala açıklanması gereken bu birkaç noktayı ayrı bir başlık olarak anlatmam gerekecek. Şimdilik bu kadar.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s