2013-09-29 15 views
7

Dahili bir sınıf SynchronizedCollection var - iki kurucu ile birlikte java.util.Collections . İlk koleksiyon alır ve diğer toplama ve bir muteks alır. eski kurucu, boş olmadığından bağımsız değişkenini denetler. ama sonra yok! burada uygulama. i ikinci kurucusuna boş göndererek değişmeyen sınıfını kırabilir bu uygulamasıylaJava SynchronizedCollection sınıfındaki bu bir hata mı?

SynchronizedCollection(Collection<E> c) { 
     if (c==null) 
      throw new NullPointerException(); 
     this.c = c; 
     mutex = this; 
    } 
SynchronizedCollection(Collection<E> c, Object mutex) { 
     this.c = c; 
     this.mutex = mutex; 
} 

. kendimi ikna edemez ancak Josh Bloch ve Neal Gafter bu göremiyordu

SynchronizedCollection(Collection<E> c) { 
     this(c,this) 
    } 
SynchronizedCollection(Collection<E> c, Object mutex) { 
     if (c==null) 
      throw new NullPointerException(); 
     this.c = c; 
     this.mutex = mutex; 
} 

:

ben böyle bir şey olması gerektiğine inanıyoruz. Bana neyi özlediğimi gerçekten söyler misin? düzenlenmiş


: bu kurucular

Map<String, String> m = new Map<String, String>(){ 

     @Override 
     public int size() { 
      // TODO Auto-generated method stub 
      return 0; 
     } 

        . 
        . 
        . 

     @Override 
     public Collection<String> values() { 
      return null; 
     } 


    }; 

    Map<String, String> synchronizedMap = Collections.synchronizedMap(m); 
    Collection<String> values = synchronizedMap.values(); 

cevap

11

Elbette bu bir hatadır. Her iki kurucu da tutarlı olmalı, her ikisi de bir istisna atmalı veya hiçbiri atmamalı.

Bu Şimdi hem kurucular özel durum oluşturur Java 8. giderilmiştir:

SynchronizedCollection(Collection<E> c) { 
    this.c = Objects.requireNonNull(c); 
    mutex = this; 
} 

SynchronizedCollection(Collection<E> c, Object mutex) { 
    this.c = Objects.requireNonNull(c); 
    this.mutex = Objects.requireNonNull(mutex); 
} 
2

Hem paketi korunmuş ve sadece ilk olan muhtemel saldırı muhtemelen Collections arasında publicsynchronizedList() ve synchronizedSet() yöntemlerle bir null bağımsız değişken ile birlikte kullanılabilir.

Diğer yapıcı dahili olarak (Collections sınıfında) kullanılır ve ilk argüman, çeşitli uygulamalarda (arama kodu) hiçbir zaman null olamaz, böylece onu kırmazsınız.

Her zaman java.util paketinde bir şeyler oluşturmayı deneyebilirsiniz, ancak büyük olasılıkla bir SecurityException elde edersiniz.

+2

elimden Harita arayüzünü genişletir yöntem java.util paketinde benim uygulanmasını koymadan boş dönmek() geçersiz kılma değerleri! Nesne, değerler() yöntemi ile döner, ikinci kurucuya gönderir - bkz. Collections.synchronizedMap() ve Bom! –

+0

düzenleme notuma bakın –

+1

@MortezaAdi Adil davranmak, bu davranışı açıkça izin vermeyen Map.values ​​() 'ın sözleşmesini kötüye kullanmak olarak tartışılabilir. (Bu, ya da izin vermez, ama: hiç ** "inputSet()", 'keySet()' veya 'değerler()' dönüş değerlerini sıfırdan kontrol edermisiniz? Yani?) Size sınıfın sağlamlıktan yoksun olduğunu söyleyeyim ancak API'yı kötüye kullanmadan onu kırmanın bir yolu yok. Sotirios'a, bir şekilde üçüncü taraf kodunda bir kırılmaya neden olursanız daha fazla sorun olacağına katılıyorum. – millimoose

İlgili konular