Как в JDK 1.6 реализован SQLException.iterator() и как это можно упростить
Начиная с 1.6, SQLException реализует Iterable; подробности здесь.
От нас потребуется изменить инициализацию полей с вот такой:
на вот такую:
и переписать метод next() в виде:
Разумеется, переписанный hasNext() будет выглядеть след. образом:
Собственно, вот и все дела.
public Iterator<Throwable> iterator() {
return new Iterator<Throwable>() {
SQLException firstException = SQLException.this;
SQLException nextException =
firstException.getNextException();
Throwable cause = firstException.getCause();
public boolean hasNext() {
if(firstException != null || nextException != null
|| cause != null)
return true;
return false;
}
public Throwable next() {
Throwable throwable = null;
if(firstException != null){
throwable = firstException;
firstException = null;
}
else if(cause != null){
throwable = cause;
cause = cause.getCause();
}
else if(nextException != null){
throwable = nextException;
cause = nextException.getCause();
nextException = nextException.getNextException();
}
else
throw new NoSuchElementException();
return throwable;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}- Во-первых, метод hasNext() реализован по-идиотски.
if (<булевское выражение>) then return true; else return false; --
признаться, я давно такого не видел. Они б ещё return <булевское выражение> ? true : false ? true : false; написали. - Во-вторых, одно поле (firstException) и одну локальную переменную (throwable в next()) можно к чертям выкинуть. Изменённый код медленнее понимается новичками (которые всё равно чужого кода не читают), но зато самую малость элегантнее.
От нас потребуется изменить инициализацию полей с вот такой:
SQLException firstException = SQLException.this; SQLException nextException = firstException.getNextException(); Throwable cause = firstException.getCause();
на вот такую:
SQLException nextException = SQLException.this; Throwable cause = null;
и переписать метод next() в виде:
public Throwable next() {
if (!this.hasNext()) {
throw new NoSuchElementException();
}
final boolean causeNull = this.cause == null;
try {
return causeNull ? this.nextException : this.cause;
} finally {
this.cause = (causeNull
? this.nextException
: this.cause).getCause();
if (causeNull) {
this.nextException =
this.nextException.getNextException();
}
}
}Разумеется, переписанный hasNext() будет выглядеть след. образом:
public boolean hasNext() {
return this.nextException != null || this.cause != null;
}Собственно, вот и все дела.
