Deneyin-ile-kaynakları blok yönetme birden çok zincirleme kaynakları için deyim doğru mu?
Java 7-ile-kaynakları deneyin(ayrıca KOL bloğu olarak bilinen ( . sözdizimi ^em>Otomatik Kaynak Yönetimi)) tek AutoCloseable
kaynak kullanırken güzel, kısa ve basittir. Ancak, birbirine bağlı olan birden fazla kaynak belirtmeni istiyorum ne zaman doğru deyim, örneğin ne olduğundan emin değilim sardığı FileWriter
BufferedWriter
Bir bir. Tabii ki, bu soru AutoCloseable
bazı kaynaklara alınmış herhangi bir zaman, sadece bu iki özel sınıfları ilgilendiriyor.
Üç aşağıdaki seçenekleri geldi:
1)
Gördüğüm naif bir deyim KOL tarafından yönetilen değişken: üst düzey tek sarıcı bildirmektir
static void printToFile1(String text, File file) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Bu güzel ve kısa, ama bozuldu. FileWriter
temel bir değişken olarak bildirilmedi çünkü, asla doğrudan finally
oluşturulan blok içinde kapalı olacak. Sarma close
yöntemi BufferedWriter
sadece kapalı olacak. Sorun, bir özel durum bw
'nin kurucu, close
dolayısıyla FileWriter
temel adlı olmayacaktır . atılırsa, ^strong>kapatılmayacak.
2)
static void printToFile2(String text, File file) {
try (FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Burada, temel ve kaydırma kaynak, her iki KOL tarafından yönetilen değişkenleri, ikisi de kesinlikle kapalı olacak, kesinlikle öyle fw.close()
temel olduğunu ilan ettiiki kez aradıilk sarma bw.close()
ile ikinci kez doğrudan ve.
Bu olmamalı bir sorun için bu iki özel sınıflar uygulamak Closeable
(bir alt tür AutoCloseable
), kimin sözleşme bildiren birden çok arama close
izin:
Bu akış ve herhangi bir sistem kaynaklarını ilişkili bültenleri kapatır. Eğer akışı zaten kapalı ise, o zaman bu yöntemi çağırmadan hiçbir etkisi olmaz.
Ancak, genel bir durum, ben kaynaklarını bunu uygulamak sadece AutoCloseable
(Closeable
), yok garanti close
çağrılabilir birden çok kez:
Java close yöntemi farklı olduğunu unutmayın.ıo.Closeable, bu yöntem yakın idempotent olması gerekli değildir. Diğer bir deyişle, bir kez daha bu kadar yakın yöntemin çağrılması, bazı görünür yan etkisi, Closeable farklı olabilir.eğer birden fazla kez aradım, hiçbir etkisi yoktur için gerekli olan yakın. Ancak, bu arabirimin uygulayıcı şiddetle yakın yöntemlerini idempotent yapmak için teşvik edilir.
3)
static void printToFile3(String text, File file) {
try (FileWriter fw = new FileWriter(file)) {
BufferedWriter bw = new BufferedWriter(fw);
bw.write(text);
} catch (IOException ex) {
// handle ex
}
}
Bu sürüm fw
yalnızca temizlenmesi gereken gerçek bir kaynak temsil eder, çünkü teorik olarak doğru olması gerekir. bw
kendini herhangi bir kaynak tutmak değil, sadece fw
temel kapatmak için yeterli olmalı fw
tek delege.
Öte yandan, sözdizimi biraz düzensiz ve ayrıca, Tutulması konuları bir uyarı, sanırım bir yanlış alarm, ama yine de bir uyarı Bu bir anlaşma ile
Kaynak sızıntısı: 'bw' asla kapalı
Hangi gitmek için yaklaşım? Yoksa başka bir deyim özledimdoğrubir?
CEVAP
İşte benim alternatifler üzerinde:
1)
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
bw.write(text);
}
Benim için en iyi şey, geleneksel C 15 yıl önce Java geliyor programınızı sana bana güven. Eğer işler genellikle yaptıkları pisliğe ve yanlış ise bile, kodun geri kalan gül En iyi davranış ve koklamak istiyorum. Nitekim BufferedWriter
bir istisna atar. Bellek çalışan sıradışı, örnek olmaz. Diğer dekoratörler için, onların kurucular kontrol edip bir istisna biliyor musunuz? Bilmiyorum. Çok iyi eğer bu tür belirsiz bilgi üzerine dayanan bir tablo gibi duvara asılmak kodu yapmaz.
De var "". imha Eğer bir hata durumu varsa, o zaman muhtemelen silinmesi gereken bir dosya için çöp (gösterilmez kod) kızarma olmak istemiyorum. Tabii ki, dosya silme, ancak aynı zamanda hata işleme yapmak için ilginç bir operasyon.
Genellikle finally
bloklar mümkün olduğunca kısa ve güvenilir olmak istiyorum. Basması ekleyerek bu hedefe yardımcı olmuyor. Birçok sürümleri için FIRSATLAR arabelleği dersleri close
içinde flush
bir istisna dekore edilmiş nesne close
denir neden bir hata vardı. Bir süre için sabit olmuştur buna rağmen diğer uygulamalardan bunu bekliyor.
2)
try (
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw)
) {
bw.write(text);
}
Hala flushing örtülü sonunda blok (şimdi tekrar close
- bu-daha da kötüsü olarak eklemek daha dekoratörler), ama inşaat güvenli ve örtülü son taşları bile başarısız flush
gelmez önlemek kaynağı serbest bırakmak.
3)
try (FileWriter fw = new FileWriter(file)) {
BufferedWriter bw = new BufferedWriter(fw);
bw.write(text);
}
Burada bir hata var. Olmalıdır:
try (FileWriter fw = new FileWriter(file)) {
BufferedWriter bw = new BufferedWriter(fw);
bw.write(text);
bw.flush();
}
Kötü uygulanan bazı dekoratörler aslında kaynak ve güvenilir bir şekilde kapalı olması gerekir. Aynı zamanda bazı dereler belirli bir şekilde kapatılması için sıkıştırma ve bitirmek için bit yazma için yapıyorlar, ve sadece her şeyi temizler. (belki gerekebilir
Kararı
3 teknik olarak üstün bir çözüm olsa da, yazılım geliştirme sebep 2 daha iyi bir seçim yapmak. Ancak,--kaynak deneyin hala yetersiz bir düzeltme, Java SE 8'de kapatma ile daha net bir sözdizimi sahip olması gereken deyim Etrafında Yürütmek, devam etmelisin.
LogCat mesaj: Google Play hizmetleri k...
Nasıl libs klasöründe kavanoz için jav...
URL Java sınıf kaynakları yüklemek içi...
Django bir sayfada birden fazla form i...
Gereken "Atma" tek tip yönet...