特定の値を検索するときにClassCastExceptionを静かにキャッチするのは安全ですか?
-
10-10-2019 - |
質問
ソート付きコレクションを実装しているとします(簡単な例-A Set
ソートされた配列に基づいています。)この(不完全な)実装を検討してください。
import java.util.*;
public class SortedArraySet<E> extends AbstractSet<E> {
@SuppressWarnings("unchecked")
public SortedArraySet(Collection<E> source, Comparator<E> comparator) {
this.comparator = (Comparator<Object>) comparator;
this.array = source.toArray();
Arrays.sort(this.array, this.comparator);
}
@Override
public boolean contains(Object key) {
return Arrays.binarySearch(array, key, comparator) >= 0;
}
private final Object[] array;
private final Comparator<Object> comparator;
}
次に、整数のセットを作成しましょう
Set<Integer> s = new SortedArraySet<Integer>(Arrays.asList(1, 2, 3), null);
特定の値が含まれているかどうかをテストします。
System.out.println(s.contains(2));
System.out.println(s.contains(42));
System.out.println(s.contains("42"));
上記の3行目はaを投げます ClassCastException
. 。私が欲しいものではありません。戻るのが好きです false
(なので HashSet
そうです。)
例外をキャッチしてfalseを返すことでこの動作を得ることができます:
@Override
public boolean contains(Object key) {
try {
return Arrays.binarySearch(array, key, comparator) >= 0;
} catch (ClassCastException e) {
return false;
}
}
と仮定します source
コレクションは正しく入力されます, 、私がこれをすると何がうまくいかないでしょうか?
解決
これにはJavadocとして問題はないと思います Collection.contains
スローすることを明確に述べています ClassCastException
オプションです。
唯一の 問題 バグがある場合はそうです どこか 例外を投げかけないと、特定することができなくなります。
他のヒント
TreeSet
クラスはaを投げます ClassCastException
互換性のない議論のために contains()
(に互換性がありません Comparator
セットで使用)。そのため、その例外を投げることには何の問題もありません。これが起こる可能性があることを文書化してください。
contains()からCCEを投げることは完全に合法です。ただし、多くのコレクションの実装はそれをキャッチし、虚偽を返します。これは完全に合法であると考えており、実際にはよりユーザーフレンドリーな動作です。
equals()では、選択肢がありません。あなたはそのCCEを捕まえなければなりません。
未確認の例外をキャッチすることは、常に汚れていると感じるはずですが、時にはそれが正しいことです。