SORU
23 EYLÜL 2012, Pazar


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
30 EYLÜL 2012, Pazar


İş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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • InfinityWard

    InfinityWard

    19 EYLÜL 2006
  • Monica Catral

    Monica Catra

    12 NİSAN 2009
  • Tom Megalis

    Tom Megalis

    18 NİSAN 2006