リファクタリング中に奇妙なコードに出くわしました。両方の readString() メソッドの共通部分を因数分解する候補のように見えますが、それは不可能に思えます (私にとっては頭の体操です)。
private final StringBuilder readStringBuilder = new StringBuilder(128);
@Override
public String readString() throws IOException {
final int l = readInt();
if (l <= 0) {
switch (l) {
case -1: return null;
case 0: return "";
default: throw new IOException("invalid string length encoding: " + l);
}
}
readStringBuilder.setLength(0);
for (int i=0; i<l; ++i) {
readStringBuilder.append(readChar());
}
return readStringBuilder.toString();
}
@Override
public String readString(final StringCache cache) throws IOException {
final int l = readInt();
if (l <= 0) {
switch (l) {
case -1: return null;
case 0: return "";
default: throw new IOException("invalid string length encoding: " + l);
}
}
readStringBuilder.setLength(0);
for (int i=0; i<l; ++i) {
readStringBuilder.append(readChar());
}
return cache.get(readStringBuilder, readStringBuilder);
}
両方のメソッドがほとんど同じことを行うことがわかります。return ステートメントを除いて、メソッド本体は完全に同一です。しかし、早期終了出口があるため、本体を取ることができるメソッド シグネチャが見つかりません。当然、戻り値の型は StringBuilder になりますが、早期終了の場合のみ String になります...
体を別の方法に分解する方法はありますか? (そして、空の StringBuilder の toString() は、定数文字列リテラルを返す代わりに、新しい String を作成することに注意してください)
編集: StringCache の定義は次のとおりです。
public interface StringCache {
public String get(final CharSequence charSeq, final CharSequence notFoundResult);
}