12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

java.io.InputStreamなどのクラスの関係を図にしてみた

Last updated at Posted at 2018-03-19

はじめに

Java SE 7以降はいろいろと有用なクラスが増えて、直接 java.io のクラスを触ることは減っています。ですが、先日久しぶりに InputStream を生で使ったら、使い方が分からなくてググってしまったため、図にしてみました。

使ったことないクラスも多いので、実はこういう使い方もあるよという話がありましたら、コメントお願いします。

整理した結果

以下のようになりました。
ただし、これは分かりやすさを重視したもので、正確ではありません。
理由は後述します。

読み込み(InputStream, Reader)

読み込み.png

書き込み(OutputStream, Writer)

書き込み.png

正確に書かなかった理由

いろいろな理由があって、あえて不正確にしています。

入れなかったクラス

以下のクラスは外しています。

非推奨クラス

この2つは設計ミスで非推奨になったため、除外しています。

LineNumberInputStream

このクラスは、文字がバイトによって適切に表現されるという誤った認識を前提としています。

StringBufferInputStream

このクラスでは、文字からバイトへの変換が正しく行われません。

フィルタ

この2つは単独で使用されることがないため、除外しています。何で abstract になるように設計しなかったのか?と思ったのですが、同じ疑問を持った人は他にもいるようです。

java - Why FilterInputStream is not Abstract Class - Stack Overflow

自分としては、この FilterOutputStream はそもそもいらないと思います。

図に入らなかっただけ

これらはしっくり来る位置が見つからなかったので除外しています。
たぶんパイプは独立した図にしたほうがいいと思います。

SequenceInputStream は使ったことないのですが、 InputStream を連結するという特殊なクラスなので、図に入れるとしても隅っこでぼっちになるかなと。

継承関係は記載しない

例えば、 DataInputStream, ObjectInputStreamInputStream を継承していますが、省いています。 DataOutputStream, ObjectOutputStreamOutputStream を継承していますが、省いています。

なぜかというと、これらはそれぞれプリミティブ型、オブジェクトを読み書きするために使うためであって、 InputStream として他に渡す場面がなさそうだからです。

これが例えば PushbackInputStream なら、「先頭の数バイトを読んでファイル形式を自動判別したあと、中身を InputStream として読み込む」といった使い方が想定されます。

あと、 ObjectInputStream は InputStream を直接継承していますが、 DataInputStreamFilterInputStream を間に挟んでいるのも分かりにくい理由だと思います。同様の疑問を持った人は他にもいるようです。

整理して気づいたこと

命名規則が分かりにくい

  • 入力元・出力先
  • フィルタ
  • 加工

これらが全て XXXInputStream, XXXOutputStream, XXXReader, XXXWriter という命名規則になっています。そのため区別が付きづらく、混乱の元になっています。

エンコーディングの扱いがバラバラ

図で背景に色を付けた3つのクラスについては、エンコーディングの扱いが微妙です。

FileReader, FileWriter には、エンコーディングを指定するコンストラクタがありません。なので、図には入れましたが、無視した方がいいです。FileReader は遅いという話もありますし、今なら Files#newBufferedReader があります。

PrintStreamPrintWriter があるので、扱いがよく分かりません。

PrintWriterクラスは、バイトではなく文字を書き込むことが必要な状況で使用されます。

と書かれていますが、単に System.outSystem.err のために残しているのでは?と思います。

おわりに

図にしてみると、意外とシンプルでした( ´ω`)

あと、リンク貼るのに時間をかけるのはどうかと思いました(´・ω・`)

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?