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

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

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

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

Q&A

解決済

3回答

7863閲覧

try catch finally 文のテキストがコンパイルエラー

tkh

総合スコア13

Java

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

1グッド

2クリップ

投稿2016/01/18 10:49

編集2016/01/18 11:02

始めまして。初心者で学習中のものです。

いま使用している教材(Java8対応と謳っている)でtry catch finally文の説明の項目があるのですが、例題があり「以下のコードで解決しましたね」という話のになっているのですが、実行してみるとコンパイルエラーが起きます。

この教材ではちょくちょくそういった物があるにもかかわらず説明がない為、四苦八苦しています。

コンパイルエラーになる原因をご教授いただけたら幸いです。

よろしくお願いします。

java

1import java.io.*; 2 3public class Main { 4 public static void main(String[] args) { 5 FileWriter fw = null; 6 try { 7 fw = new FileWriter("data.txt"); 8 fw.write("hello!"); 9 } catch (IOException e) { 10 System.out.println("エラー" ); 11 } finally { 12 fw.close(); 13 } 14 } 15} 16 17例外IOExceptionは報告されません。スローするには、補足または宣言する必要があります。 18 fw.close(); 19 ^ 20
kozuchi👍を押しています

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

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

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

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

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

guest

回答3

0

Java8対応だというのなら、次のような書き方があります。
Java7で導入されたtry-with-resourcesという構文です。

java

1import java.io.*; 2 3public class Main { 4 public static void main(String[] args) { 5 try(FileWriter fw = new FileWriter("data.txt")) { 6 fw.write("hello!"); 7 } catch (IOException e) { 8 System.out.println("エラー" ); 9 } 10 } 11}

tryのあとの括弧にリソースを指定します。(具体的には、AutoClosableインタフェースを実装しているクラス)
この構文を使えば、tryを抜ける際に指定されたリソースのclose()処理が自動で行われ、closeでの例外処理を気にする必要がなくなります。

投稿2016/01/18 14:02

編集2016/01/18 17:57
swordone

総合スコア20649

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

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

kozuchi

2016/01/18 14:05

Java が C# に負けてるなと思っていた点ですが、機能追加されていたのですね。 勉強になりました。
tkh

2016/01/18 18:08

ご回答いただきありがとうございます。 この構文については、問題のコードの次に紹介されていました。 教材では問題のコードのfw.close()を置き去りのまま、この構文の項目へ進んでたので混乱していました。 ありがとうございました。
guest

0

ベストアンサー

そんな使えない教材は捨てたほうがいいですよ。

まず、コンパイルエラーが出る原因ですが、FileWriter.close() のメソッド自体を FileWriter クラスのリファレンスなどを調べてみると解ると思うのですが、このメソッドは例外 IOException への対処を必要とします。しかし、その教材のコードでは行われていませんね。

それ以外にも、(何らかの原因で) FileWriter の生成に失敗した場合、fw は null のままになる可能性があるわけですが、finally ではその対処も無いため、null を指し示している fw に対して close() を呼んでしまう可能性があります。ちなみに、その場合、NullPointerException の例外が発生してしまうでしょう。

例外をどこでどう捉えるか?で幾つか書き方はありますが、例えば、以下のような書き方があります。

Java

1FileWriter fw = null; 2try { 3 try { 4 fw = new FileWriter("data.txt"); 5 fw.write("hello!"); 6 } finally { 7 if (null != fw) fw.close(); 8 fw = null; // 腐った参照になるのを防ぐため null を代入しておく 9 } 10} catch (IOException e) { 11 System.out.println("エラー"); 12}

上記のコードでは FileWriter が生成できなかった事を考慮して null との比較を行った上で、(null ではない、つまり)存在すれば close() を呼び出しているわけですが、null のままの状況が起こっている時点で動作は破綻しているため、開発対象によっては、ここまで厳密に捉えなくても良いと思います。しかし、こういった挙動を理解せずに省略するのは危険ですので、色々な対処方法は知っておくべきです。

以上、ご参考になれば幸いです。

投稿2016/01/18 11:56

編集2016/01/18 12:07
ps13zier

総合スコア433

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

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

tkh

2016/01/18 18:35 編集

ご回答いただきありがとうございます。 出来るだけ自分で理解して対処できるようになりたいと思っています。まだ学習段階でFileWriterが生成できないというケースに遭遇したことも考えたこともなかったので、大変参考になりました。 私の現学習段階でps13zierさんのコードは理解するのに時間がかかりましたが、 ファイルを書込み禁止にしたり、削除したりなどの不足の事態を自分で発生させ実験してみたところ、このコードが様々なケースに対応してあり、大変勉強になりましたのでベストアンサーとさせていただきました。 ありがとうございました。
guest

0

こんにちは。
分かる範囲でお答えします。

まず、try-catchっていうのは、
try-catchで囲まれた中で発生したExceptionを拾うような動きをします。

なので、

fw = new FileWriter("data.txt");
fw.write("hello!");

でIOExceptionが発生すると、

} catch (IOException e) {
System.out.println("エラー" );
}

が拾ってくれるのです。

では、fw.close()はどうでしょう?
finallyの中に記述されていますが、
IOExceptionが発生すると、誰がcatchしてくれますか?

答えは、「残念ながら誰もcatchしません」です。

finallyは、try-catchで何があっても、最後に必ず実行する部分です。
従って、catchの部分は既に通り過ぎてしまっているのです!!!

じゃあどうしたらいいのか?
答えは二つあります。

1.fw.close()も、try-catchに入れちゃう。

fw = new FileWriter("data.txt");
fw.write("hello!");
fw.close();

こんな感じですね。これなら、fw.close()でIOExceptionが発生しても、
catchが拾ってくれますよね!?

2.finallyの中にtry-catchを書いてしまう。

}finally{
try{
fw.close();
}catch( IOException e ){
System.out.println( "finallyでIOException発生!" );
}
}

上記のような感じです。
これなら、finallyの中のfw.close()でIOExceptionが発生しても、
catchが拾ってくれますよね!?

こんな具合に、好きな方を選ばれると良いと思います。

ちなみに、Exception(エラー)は、想定外のものも発生します。

catch( IOException e )

これだけだと、IOExceptionが発生した時にしか、
catchに入ってくれません。。。
何が起こるか分からないのに、エラーをあらかじめ予測するなんて、困りますよね?

なので、全てのExceptionを網羅する以下の記述を加えることをお勧めします。

}catch( Exception e ){
System.out.println( "エラーをキャッチ!" );
System.out.println(e);
}

最初は慣れないと思いますが、
是非頑張ってください!

投稿2016/01/18 11:49

hentai_nabe

総合スコア94

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

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

tkh

2016/01/18 17:41

ご回答いただきありがとうございます。 1.の方法で例外がおきたときにファイルが開きっぱなしになるのを回避するコードが今回の問題のコードで解決っていうことでfinallyを学習するものだったのです。 2.の方法のご説明をいただきようやく理解ができました。教材の説明より判りやすく大変助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問