先のJDK1.1の想定しているシナリオを、もう一度、良く見て下さい。 コード変換が行われるのは、外部のデータが内に入る所と、内部のデータが外に出る 所の二ヶ所です。プログラムの中で、データ毎に変換する訳ではありません。 二ヶ所のデータの流れ道にコンバータを仕掛けておけば、これ以外の所でコード変換を する必要はないのです。
JDK1.1では、Byte stream を処理するInputStream,OutputStreamの系列クラスとは 独立に、Byte Stream を InputStreamから読み込んで、Unicodeにコード変換を行って Character Stream をつくり出す InputStreamReaderクラスと、Unicodeからなる Character Streamを、他のコードに変換して、そのByte Stream をOutputStreamに 書き出す、OutputStreamWriterクラスという、Character Stream の処理を行う 二系列のクラス群が新たにつけ加わりました。
InputStreamReaderはInputStreamに、OutputStreamWriterはOutputStreamに 対応していて、byteとcharの違いはあるのですが、それぞれ同じ働きをする メソッドを備えています。
次のリストは、InputStreamReaderのコンストラクタの定義の一部です。 これを見れば、たとえば、new InputStreamReader( System.in )で生成される 入力ストリームは、明示的にコンバータの指定はないのですが、getDefault()で 獲得されるコンバータを利用出来る事がわかります。 OutputStreamWriterについても 同じです。全てのコンストラクタが、最終的には、 InputStreamとConverterと、バッファーサイズの三つの引数を持った最後の コンストラクタによって、定義されていることを確認してください。
public InputStreamReader(InputStream inputStream) { this(inputStream, ByteToCharConverter.getDefault()); } public InputStreamReader(InputStream inputStream, String string) throws UnsupportedEncodingException { this(inputStream, ByteToCharConverter.getConverter(string)); } private InputStreamReader(InputStream inputStream, ByteToCharConverter byteToCharConverter) { ......................... }
この最後のコンストラクタがprivateなコンストラクタとされていることに 注意して下さい。explicitにConverterを引数としてとる、このコンストラクタは、 このクラスの中では利用できますが、クラスの外からは、全く見えなくなって しまいました。独自にConverterを作るのは、今でも出来ることは出来るのです。 ただ、そのConverterを、入出力に「仕掛ける」ことが、出来なくなってしまい ました。結局、入出力ストリームに「仕掛ける」ことのできるConverterは、 あらかじめ、sun.ioパッケージ下に用意されたConverterだけで、しかも、名前で 設定するという仕様になりました。以前の仕様と比べるとだいぶ窮屈なものになり ました。