Так что, похоже, оба метода плохие. Я действительно публикую этот ответ только для того, чтобы объединить информацию в один пост.
TofuBeer указал на упущенный недостаток в логике для метода 1, где есть другие исключения, которые могут быть выброшены, которые не будут перехвачены. В общем, всегда плохо пытаться отловить исключения для исключительных условий.
Пол указал, что то, что я считал безопасным составом, на самом деле не так. Я ожидал, что универсальный набор будет применен к выходному приведению, однако он вернет Object []. Как он указывает, я мог бы использовать временный набор для хранения данных, пока я ищу ноль.
Кроме того, как подтвердил Том, вполне возможно, что аргумент коллекции может изменяться одновременно, так что защитная копия в новый объект является хорошей идеей).
Итак, я предполагаю, что желаемый метод:
public boolean addAll( Collection<? extends E> c ) {
if ( null == c ) {
throw new NullPointerException( "c cannot be null" );
}
// Create a defensive copy to prevent concurrent modifications of c
Set<E> tmpSet = new HashSet<E>( c );
/*
* We have to iterate through the entire collection to check for
* a null. This won't take advantage of any optimizations that
* c.contains may be using.
*/
for ( E e : tmpSet ) {
if ( null == e ) {
throw new NullPointerException( "c cannot contain nulls" );
}
}
return this.wrapperSet.addAll( tmpSet );
}