Factoring out common code when the common code has multiple incompatible return types
===

I just stumbled over a weird piece of code while refactoring. It looks like a candidate for factoring out the common to both readString()-methods, only it seems to be impossible:

	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);
	}

You see that both methods do *almost* the same, the method body is completely identical, except for the return statement. But since there are early termination exits, I can't find a method signature that can take the main body - natuarally the returns type would be StringBuilder, only in the early termination case it would be String...

Any ideas how to factor the body into a separate method? (and take note that toString() on an empty StringBuilder does *create* a new String instead of returning a constant string literal)