Sonlandırma yöntemi, kapatılabilir arabirim ve kaynakları deneyin (Java 7) - 1

"Merhaba, Amigo!"

"Sizinle finalize () yöntemini tartışmaya karar verdim ."

"Hatırlarsanız, finalize() bir nesne tarafından çöp toplayıcı onu yok etmeden önce çağrılan özel bir yöntemdir."

"Bu yöntemin ana amacı, dosyaları, G/Ç akışlarını vb. kapatarak kullanılan harici Java dışı kaynakları serbest bırakmaktır."

"Maalesef bu yöntem beklentilerimizi karşılamıyor. Java sanal makinesi bir nesneyi yok etmeyi ve finalize yöntemini çağırmayı istediği kadar erteleyebilir. Üstelik bu yöntemin kalıcı olacağını da garanti etmez. "optimizasyon" adına çağrılmadığı pek çok durum var."

"Sizin için iki referansım var:"

Joshua Bloch bu yöntem hakkında güzel bir makale yazdı: link
Kısa bir alıntıyı başka kelimelerle ifade edeceğim:

  1. finalize() yalnızca iki durumda kullanılabilir:
    1. Günlüğe kaydetme ile kaynakları doğrulamak veya temizlemek için.
    2. Kaynak sızıntıları için kritik olmayan yerel kodla çalışırken.
  2. finalize(), nesneleri temizlemede GC'yi 430 kat daha yavaşlatır
  3. finalize() çağrılmayabilir
Bir röportajda kesinleşmenin, varlığı bile kafa karıştıran zararlı ve tehlikeli bir koltuk değneği olduğunu söylesem, haksız mıyım?

"Eh, bu benim günümü güzelleştirdi, Ellie."

"Java 7'de finalize yöntemini değiştirecek yeni bir ifade var . Buna try-with-resources deniyor. Bu gerçekten finalize yerine alternatif bir yaklaşım değil ."

"Try-catch gibi, ama kaynaklarla mı?"

"Neredeyse try-catch gibi. Finalize () yönteminden farklı olarak , try- catch-finally deyimindeki nihayet blok her zaman yürütülür. Programcılar ayrıca kaynakları boşaltmaları gerektiğinde bu tekniği kullandılar. konuları kapat vb.
 "İşte bir örnek:"

InputStream is = null;
try
{
 is = new FileInputStream("c:/file.txt");
 is.read();
}
finally
{
 if (is != null)
 is.close();
}

" Try bloğunun düzgün yürütülüp yürütülmediğine veya bir istisna olup olmadığına bakılmaksızın , finally bloğu her zaman çağrılır ve işgal edilen kaynakları orada serbest bırakmak mümkündür."

"Yani, Java 7'de, bu yaklaşımın resmi hale getirilmesine karar verildi, şu şekilde:"

try(InputStream is = new FileInputStream("c:/file.txt"))
{
 is.read();
}

"Bu özel try ifadesine , try-with-resources denir (koleksiyonların foreach adlı bir alternatifinin olmasına benzer şekilde ).

"Try'den sonra değişkenlerin bildirildiği ve nesnelerin yaratıldığı parantezler olduğuna dikkat edin. Bu nesneler, süslü parantezlerle gösterilen try bloğu içinde kullanılabilir. Try bloğu bittiğinde, normal veya orada bitip bitmediğine bakılmaksızın yürütülür. bir istisnaydı, parantez içinde oluşturulan tüm nesnelerde close() yöntemi çağrılacaktır."

"Ne kadar ilginç! Bu notasyon öncekinden çok daha derli toplu. Henüz anladığımdan emin değilim."

"Düşündüğün kadar zor değil."

"Öyleyse parantez içinde her nesnenin sınıfını belirtebilir miyim?"

"Evet, elbette, yoksa parantezlerin pek bir faydası olmazdı."

"Ve try bloğundan çıktıktan sonra başka bir yöntemi çağırmam gerekirse, bunu nereye koyacağım?"

"Burada işler biraz daha incelikli. Java 7, aşağıdaki arabirimi sunuyor:"

public interface AutoCloseable
{
 void close() throws Exception;
}

"Sınıfınız bu arabirimi uygulayabilir. Ve sonra onun nesnelerini bir try-with-resources deyimi içinde kullanabilirsiniz. Yalnızca bu tür nesneler, «otomatik kapanma» için bir try-with-resources deyiminin parantezleri içinde oluşturulabilir."

"Başka bir deyişle, nesnemi «temizlemek» için close yöntemini geçersiz kılmam ve içine kod yazmam gerekiyor ve başka bir yöntem belirtemiyorum?

"Evet. Ama birkaç nesne belirtebilirsiniz; bunları noktalı virgülle ayırmanız yeterli:"

try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
 is.read();
 os.write();
}

"Bu daha iyi, ama umduğum kadar havalı değil."

"O kadar da kötü değil. Buna alışırsın. Zamanla."