2

新しいタイプのバイト ストリーム (OutputStream と同様) を定義するとします。

public interface MyByteStream {
    public void write(byte[] data) throws IOException;
}

また、文字列をバイト ストリームに書き込めるヘルパー クラスがあり、柔軟性のために、通常の OutputStream または新しい MyByteStream のいずれかで動作するように、そのメソッドの 2 つのバージョンが必要です。

public class StringWriter {
    public void write(String string, MyByteStream stream) throws IOException {
        stream.write(string.getBytes());
    }

    public void write(String string, OutputStream stream) throws IOException {
        stream.write(string.getBytes());
    }
}

ここで、次のように、OutputStream を拡張してMyByteStreamを実装するクラスがあるとします。

public class DebugStream extends OutputStream implements MyByteStream {
    @Override
    public void write(int b) throws IOException {
        System.out.println(b);
    }
}

次のように StringWriter の書き込みメソッドを呼び出すことはできません。

new StringWriter().write("Hello", new DebugStream());

次のエラーが表示されるためです。

The method write(String, MyByteStream) is ambiguous for the type StringWriter

次のように、DebugStream をバイト ストリームの 1 つに明示的にキャストすることで、問題を解決できます。

new StringWriter().write("Hello", (OutputStream) new DebugStream());
new StringWriter().write("Hello", (MyByteStream) new DebugStream());

しかし、この 2 つのメソッドはどちらにしてもまったく同じことを行うため、どこでもキャストを行う必要はありません。これを回避する方法はありますか?このようなあいまいな呼び出しに対して優先されるメソッドの 1 つを定義するのは好きですか? それとも、いくつかのジェネリックのトリックですか?

ノート:

コンパイル時の型安全性を維持したいので、次の行に沿った「解決策」が出ています。

public class StringWriter {
    public void write(String string, Object stream) throws IOException {
        if (stream instanceof OutputStream) {
            ((OutputStream) stream).write(string.getBytes());
        } else if (stream instanceof MyByteStream) {
            ((MyByteStream) stream).write(string.getBytes());
        } else {
            throw new IllegalArgumentException();
        }
    }
}
4

1 に答える 1