- PR -

JAVA言語の作法について

投稿者投稿内容
masa
大ベテラン
会議室デビュー日: 2005/05/11
投稿数: 108
投稿日時: 2005-09-21 09:02
おはようございます。

引用:

try-catch句ですが、一度そのように組んでみたのですが、
The local variable bwriter may not have been initialized
と初期化されていない可能性があるエラーがでてしまい、実行できません・・
また、Nullで初期化したところストリームのClose時にNullPointerExceptionが発生してしまいます。自分の考え方がおかしいのでしょうか・・


Javaの作法を知るには言語仕様を把握する必要があるかと思います。
全てを一度に詰め込むことは大変ですが、発生した疑問はその都度潰してから
先へ進むのが後々役に立ちますよ。
今回のケースだと、
何故
The local variable bwriter may not have been initialized
のメッセージが出力するのか、
何故
NullPointerException
が発生するのかを把握することが一番大事です。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-09-21 09:13
引用:

さるさんの書き込み (2005-09-20 20:15) より:

じゃんぬねっとさんが↑のようにおっしゃってますねぇ〜。
さあ、意味を考えよう♪
ヒント http://www.javaroad.jp/java_exception2.htm


そういえば、私も Java やってた頃は入れ子にせずに、
まとめて同じ finally 句にかけていたなぁ。(null チェックはしてたけど...)


_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
武澤
常連さん
会議室デビュー日: 2004/09/27
投稿数: 31
投稿日時: 2005-09-21 10:10
引用:

try-catch句ですが、一度そのように組んでみたのですが、
The local variable bwriter may not have been initialized
と初期化されていない可能性があるエラーがでてしまい、実行できません・・
また、Nullで初期化したところストリームのClose時にNullPointerExceptionが発生してしまいます。自分の考え方がおかしいのでしょうか・・



推察どおり、初期化されない可能性があるソースになっていたのでしょう。
例えば
コード:
BufferedReader reader;
BufferedWriter writer;

コード:
BufferedReader reader = null;
BufferedWriter writer = null;


とすれば、初期化されます。
また、colse時のNullPointerExceptionはnullチェックをすればよいでしょう。
※しかし、nullだった時の動作をどうするかはケースバイケースですね。
コード:
if (reader != null ) {
    reader.close();
    reader=null; // Javaでは2度目のCloseは問題ないけど気持ち悪いので・・・これは自分の癖です。
}

kipple
会議室デビュー日: 2005/09/20
投稿数: 6
投稿日時: 2005-09-21 15:34
>masa 様
アドバイスありがとうございます。
今回の原因については武澤様が書いていただきましたが、言語仕様について深く理解していく必要性を感じました。
一歩づつ、前にすすめるよう「発生した疑問はその都度潰して」を心に留めておきます。

>じゃんぬねっと 様
ヌルチェック・・
これですね。いまいちnullについての認識が甘かったのを反省しています。

>武澤 様
お書きいただいたコードで完全に動きました。ありがとうございます。
そのまま修正するのも能がないと思い、調査時に見つけたnull objectパターンというものを試してみました。
多分また変なところがあるとは思いますが、自分の理解度を図る意味で修正ソースを載せさせて頂きます。

コード:
private class NullReader extends Reader {
	public void close(){}
	public int read(char[] cbuf, int off, int len){
		return 0;
	}
}
private class NullWriter extends Writer {
	public void close(){}
	public void flush(){}
	public void write(char[] cbuf, int off, int len){}
}

public void extractFile() throws IOException {
	Reader reader = new NullReader();
	Writer writer = new NullWriter();
	try{
		reader = new BufferedReader(new FileReader(inputFileName));
		writer = new BufferedWriter(new FileWriter(outputFileName));
		boolean isToWrite = false;//書き出すべきか?
		String line;
		while ((line = ((BufferedReader)reader).readLine()) != null) {//EOFまで読み込み
			if (isToWrite) {//書き込みモードか?
				writer.write(line);
				((BufferedWriter)writer).newLine();
				if (p2.matcher(line).find()) {//終了文字列にマッチ
					isToWrite = false;
				}
				continue;
			}
			if (p1.matcher(line).find()) {//開始文字列にマッチ
				writer.write(line);
				((BufferedWriter)writer).newLine();
				isToWrite = true;
			}
		}
	}catch(FileNotFoundException e){
		throw e;
	}catch(IOException e){
		throw e;
	}finally{
		writer.close();
		reader.close();
	}
}

さる
ぬし
会議室デビュー日: 2005/07/14
投稿数: 276
お住まい・勤務地: 実家戻ったw
投稿日時: 2005-09-21 15:45
なんか全然違う方向に進んでますよ!!
武澤さんのコメントを読み直そう♪

と、思ったら俺が良く読んでないだけだったや(ヲイ)

1.5になればいらなくなるやつだっけ?<Null Objectパターン

[ メッセージ編集済み 編集者: さる 編集日時 2005-09-21 15:52 ]
明智重蔵
大ベテラン
会議室デビュー日: 2005/09/05
投稿数: 127
投稿日時: 2005-09-21 16:02
inファイルを一気に読み込んで
.に改行を含むことの出来るマッチモードを使って
正規表現を使ってマッチした結果を出力したほうが、いいと思います
こんな感じの正規表現で上手くいくと思います

^.*?start.*?end.*?$

参考サイト
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/util/regex/Pattern.html



OracleSQLパズル
http://oraclesqlpuzzle.hp.infoseek.co.jp


[ メッセージ編集済み 編集者: 重蔵 編集日時 2005-09-21 16:12 ]
c9katayama
常連さん
会議室デビュー日: 2003/02/04
投稿数: 38
投稿日時: 2005-09-21 16:08
おそらく、武澤さんの書かれたコードは一度実装してみられたのだと
思います(null初期化&nullチェッククローズ)
そのコードを一度載せてみてはどうでしょうか?

Null Objectパターンは、もちろんこのような利用方法も可能ですが、
もっと広範囲に渡ってnullチェックが必要になりそうな時に利用します。
(例えば、様々な箇所で使われるLog出力のオブジェクトなど)

この場合だとスコープ単位がメソッドレベルなので、素直にnull初期化nullチェックで
問題ないと思います。

ちなみにスコープというのは変数やメソッドなどの有効範囲のことですが、
私は「自分が気にして見なければならない範囲」、という意味でよく使っています。
tryブロックの外にあると、Stringのスコープがtrycatchのあとに続くプログラムも
スコープに入るため、例えば同じ名前の変数を使いたいときに使えなかったり、
またその変数を再利用するようなコードを書いてしまうと、可読性が損なわれます。
(はじめのプログラムでint rcを宣言して、いろんな箇所で使い回すようなコードが
該当します)
自分が気にしなければいけない範囲を狭めることで、プログラム自体の品質も上がる
のではないかな、と思っています。




[ メッセージ編集済み 編集者: c95029 編集日時 2005-09-21 16:16 ]
ひでっぷ
会議室デビュー日: 2003/12/09
投稿数: 17
投稿日時: 2005-09-21 16:20
みなさんこんにちは。
コーディング作法についてですが、私はここを参考にしましたよ。

http://www.alles.or.jp/~torutk/oojava/codingStandard/writingrobustjavacode.html

命名法からスコープについてまで幅広く書いてありますのでなかなかいいと思います。

スキルアップ/キャリアアップ(JOB@IT)