まず、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.checkedCollection
etcのユースケースの1つです。追加されたランタイムチェックは、奇妙なものが挿入されるのを防ぐのに役立ちます。
関係なくnullを処理するようにAPIを変更しましたが、エンドユーザーが実行しているJavaのバージョンによっては、クライアントコードがNPEをスローする場合とスローしない場合があることが懸念されます。それはただ壊れているように感じます。理想的には、古い動作を保持し、挿入時にnullを防止したいと思います。
私の選択肢は次のとおりだと思います。
ランタイムチェックを完全に諦めます。
心配する必要はありません。クライアントコードを信頼して、nullを挿入しないようにしてください。
私のAPIはJRE7のみをサポートすることを宣言します。
Guavaを使用してください。これは見栄えがしますが、私のAPIが追加の依存関係になります。
nullと型のチェックを強制する独自のSetラッパーをロールします。
私が見逃している他のよりエレガントなソリューション。
どんなガイダンスでも大歓迎です!