1

まず、Java7のCollections.checked*によって追加された動作を次に示します。

nullは任意の参照型の値と見なされるため、返されるコレクションでは、バッキングコレクションが挿入する場合は常にnull要素を挿入できます。

ただし、これは互換性ドキュメントに記載されていないようです。デモ:

public class MyAPI {
    private Set<Polygon> polygons = new Collections.checkedSet(new HashSet<Polygon>(), Polygon.class);
    public Set<Polygon> getPolygons() {
        return polygons;
    }
}
public class MyAPITest {
    // This JUnit test passes when using Java 6 or earlier, but fails for Java 7.
    @Test(expected=NullPointerException.class)
    public void testAddNullPolygon() {
        new MyAPI().getPolygons().add(null);
    }
}

ご覧のとおり、Setクライアントコードを公開するAPIを作成しています。私が読んだところによると、これはCollections.checkedCollectionetcのユースケースの1つです。追加されたランタイムチェックは、奇妙なものが挿入されるのを防ぐのに役立ちます。

関係なくnullを処理するようにAPIを変更しましたが、エンドユーザーが実行しているJavaのバージョンによっては、クライアントコードがNPEをスローする場合とスローしない場合があることが懸念されます。それはただ壊れているように感じます。理想的には、古い動作を保持し、挿入時にnullを防止したいと思います。

私の選択肢は次のとおりだと思います。

  1. ランタイムチェックを完全に諦めます。

  2. 心配する必要はありません。クライアントコードを信頼して、nullを挿入しないようにしてください。

  3. 私のAPIはJRE7のみをサポートすることを宣言します。

  4. Guavaを使用してください。これは見栄えがしますが、私のAPIが追加の依存関係になります。

  5. nullと型のチェックを強制する独自のSetラッパーをロールします。

  6. 私が見逃している他のよりエレガントなソリューション。

どんなガイダンスでも大歓迎です!

4

1 に答える 1

1

私が最終的に使用したオプションは、checkedCollectionを削除して、公開されたコレクションを変更できないようにすることです。APIのユーザーは、コレクションを変更するために、追加のadd / remove/clearメソッドの1つを呼び出す必要があります。

これにより、APIユーザーは多少制限されます。たとえば、addAllを使用して、1回のメソッド呼び出しで別のコレクションのすべての要素をコピーすることはできません。しかし、それは単純さと型の安全性のための公正なトレードオフです。

public class MyAPI {
    private Set<Polygon> polygons = new HashSet<Polygon>();
    private Set<Polygon> polygonsReadonlyView = Collections.unmodifiableSet(polygons);
    public Set<Polygon> getPolygons() {
        return polygonsReadonlyView;
    }
    public boolean addPolygon(Polygon p) {
        if (p == null) {
            throw new IllegalArgumentException("polygon cannot be null");
        }
        return polygons.add(p);
    }
    public boolean removePolygon(Polygon p) {
        return polygons.remove(p);
    }
    public void clearPolygons() {
        polygons.clear();
    }
}

これらすべてからの1つのポイントは、nullが挿入されるのを防ぐためにcheckedCollectionに依存しないことです。

グーグル検索はこれを示唆するかもしれません...しかしそれをしないでください!ヌルチェックは、checkedCollectionのユースケースの1つではありません。

于 2012-12-03T13:13:14.470 に答える