8

内部クラス SynchronizedCollection があります - java.util.Collections 内に 2 つのコンストラクターがあります。1 つはコレクションを取得し、もう 1 つはコレクションとミューテックスを取得します。以前のコンストラクターは、引数が null でないことを確認します。しかし、後者はしません!これが実装です。

 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;
 }

この実装では、null を 2 番目のコンストラクターに送信することで、クラスの不変条件を破ることができます。

私はそれが次のようなものであるべきだと信じています:

 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;
 }

しかし、Josh Bloch と Neal Gafter がこれを見ていないことに納得できません。ここで私が見逃したことを本当に教えてもらえますか?


編集:攻撃の可能性

    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();
4

2 に答える 2

12

確かにこれはバグです。両方のコンストラクターは一貫している必要があります。両方が例外をスローするか、いずれもスローしないかのいずれかです。

これは Java 8 で修正されました。現在、両方のコンストラクターが例外をスローします。

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);
}
于 2013-09-29T16:29:06.557 に答える
3

これらのコンストラクターは両方ともパッケージで保護されており、最初のコンストラクターのみがおよびのメソッドをnull介して引数と共に使用できる可能性があります。public synchronizedList()synchronizedSet()Collections

他のコンストラクターは内部 (Collectionsクラス内) で使用され、最初の引数はnullさまざまな実装 (コードの呼び出し) で使用できないため、それを壊すことはできません。

いつでもjava.utilパッケージ内に何かを作成しようとすることができますが、ほとんどの場合、SecurityException.

于 2013-09-29T16:19:08.793 に答える