質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1639閲覧

ReaderクラスをOverrideすると、呼び出し側と呼び出された側のreadメソッドの挙動が違う理由が知りたいです。

zoemond

総合スコア50

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/07/07 06:54

編集2016/07/07 07:25

経緯

javaを学習中です。
IOを理解するため、Readerクラスをオーバーライドして、独自のReaderを作ろうとしています。
そこで、試しに以下のようなReaderを作ってみました。
オーバーライドしていない時と挙動は一緒だと思っています。(コンストラクタのReaderを使って値を返しているので)

java

1class MyReader extends Reader { 2 Reader reader; 3 4 MyReader(Reader reader) { 5 this.reader = reader; 6 } 7 8 @Override 9 public int read(char[] cbuf, int off, int len) throws IOException { 10 int c = reader.read(); //Readerクラスで読んだものをそのまま返す 11 System.out.println("中 = " + c); 12 return c; 13 } 14 15 @Override 16 public void close() throws IOException { 17 reader.close(); 18 } 19}

そしてこのクラスを使ってテキストファイルを読み込んでみると、

java

1try (MyReader reader = new MyReader(new FileReader(SRC_FILE_PATH))) { 2 int c; 3 while ((c = reader.read()) != -1) { 4 System.out.println("外 = " + c); 5 } 6 } catch (IOException e) { 7} 8

表示結果が中(呼び出されたメソッド)と外(呼び出したメソッド)で違います。

出力結果: 中 = 65533 外 = 0 中 = 65533 外 = 0 中 = 73 外 = 0 中 = 33 外 = 0 中 = -1

といったような感じで・・・

###質問
中から返ってくるint cと外で表示されるint cは同一ではないのでしょうか?
訳をご存知の方がおりましたら、教えていただきたいです。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KiyoshiMotoki

2016/07/07 07:23

「中 = 」と「外 = 」の結果が逆ではありませんか?もう一度、ソースコードと出力結果に間違いがないか確認してみてください。
zoemond

2016/07/07 07:26

すみません、その通りでした。ありがとうございます。 修正しました。
guest

回答1

0

ベストアンサー

情報の訂正、ありがとうございます。

中から返ってくるint cと外で表示されるint cは同一ではないのでしょうか?

訳をご存知の方がおりましたら、教えていただきたいです。よろしくお願いします。

read(char[] cbuf, int off, int len)メソッドを正しくオーバーライドしていないことが原因です。

API仕様書をみると、このメソッドは以下のように定義されています。
https://docs.oracle.com/javase/jp/8/docs/api/java/io/Reader.html#read-char:A-int-int-

配列の一部に文字を読み込みます。(中略) パラメータ: cbuf - 転送先バッファー (中略) 戻り値: 読み込まれた文字数。ストリームの終わりに達した場合は -1

要するに、このメソッドは

  • 引数cbufに読み込んだ文字を格納し、読み込んだ文字を返却する
  • もしくは -1 を返却する

というふうに実装しなければなりません。

というわけで、MyReaderクラスのread(char[] cbuf, int off, int len)を以下のように修正してみてください。

Before

java

1@Override 2public int read(char[] cbuf, int off, int len) throws IOException { 3 int c = reader.read(); //Readerクラスで読んだものをそのまま返す 4 System.out.println("中 = " + c); 5 return c; 6}
After

java

1@Override 2public int read(char[] cbuf, int off, int len) throws IOException { 3 int c = reader.read(); 4 System.out.println("中 = " + c); 5 6 if (c == -1) { 7 return -1; 8 } else { 9 cbuf[0] = (char) c; // 読み込んだ文字はこの配列に格納する。 10 return 1; 11 } 12}

これで、意図通りの結果になるはずです。


ところで、ご質問のコードが必ず外 = 0となる理由は、 Reader クラスの read()メソッドの実装を見てみると分かります。
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/io/Reader.java#Reader.read%28%29

read(cb, 0, 1)の戻り値が -1 でなかった場合、return cb[0];とやっています。
しかし、zoemond様のコードではこの配列に読み込んだ文字を格納していないため、char型のデフォルト値(数値 0 で表される文字)が返却されている、というわけです。

投稿2016/07/07 07:56

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zoemond

2016/07/07 08:17

なるほど! 丁寧に回答していただきましてありがとうございます。 「引数cbufに読み込んだ文字を格納し、読み込んだ文字数を返却する」 というところの理解が全くできていませんでした。 API仕様のページは何回も見たのですが、眺めているだけでまったく理解していないことに気づきました。 また、仕様のページの気を付けてみるべき部分も回答から学ぶことができました。 zoemond様なんでとんでもないです。どうもありがとうございました!
KiyoshiMotoki

2016/07/07 08:30 編集

> API仕様のページは何回も見たのですが、眺めているだけでまったく理解していないことに気づきました。 技術書の言葉は難しいですよねw  パラメータ:   cbuf - 転送先バッファ だけで 「ここに読み込んだ文字を格納する必要があるのか」 と気づける人は、まず いないと思いますw 仕様書を読むことも大事ですが、 それに加えてzoemond様のように実際にコードを書いて、ご自分の理解が正しいか確認することが、プログラム言語を習得する上でもっとも有効な手段だと私は思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問