at backyard

Color my life with the chaos of trouble.

Javaの例外とAssertionについて学ぶ

先日Java SE 7 Programmer Ⅱを受けるということを書いたが
申込手続きをして満足して、全くJavaについて勉強をしていないという有様。。。

※TODOリストを作った時点で満足してしまい、次の日から何もしない。という人が意外といるらしい。
たぶんそれと同じような感じか。

どうやってモチベーションを上げていこうかがまず重要な今日このごろである。

1.まずは音楽をかけよう

最近進めてもらったこの曲。良い曲。

youtu.be


2.Javaで書かれたイカしたソフトウェアに触れよう!

なにがある?

d.hatena.ne.jp


3.Xcodeを閉じてSTSを立ち上げる。

Windowsマシンに入っているEclipseの起動が遅すぎて、
起動が完了するまで一人ジェンガ5周ぐらい出来そうな勢いだったので、
Mac環境に入れていた"STS(Spring Tool Suite)"でコードを書いて勉強することにする。
MacSTS入れていなかったときは、コマンドラインJava書いていたりもしたが、
Javaの場合、普通にIDE使ったほうが良いですね。。

Eclipseも遅いが、Windowsマシンのスペックにも問題があるのかもしれない。

                            • -

下記の文章は私がJavaを勉強しながら、書き散らした駄文である。
この内容には間違いがある可能性がある。

この文章は時間の経過とともに精査していくつもりです。
もし間違えなどありましたらコメント欄などから教えていただけると幸いです。

                            • -

例外とアサーションについて学んでいこうと思う


throwsキーワードについて

public class TestException {
	
	static void sampleFunc(String[] str) throws RuntimeException{
		for(int i = 0; i < str.length; i++){
			System.out.println(str[i].toString());
		}
	}
	
	public static void main(String[] args){
		try{
			String[] str = new String[3];
			str[0] = "AAA";
			str[1] = "BBB";
					
			sampleFunc(str);
			System.out.println("try : "); 
		}catch(Exception e){
			System.out.println("catch a : " + e);
		}finally{
			System.out.println("Call a Fincally");
		}
	}
}

よくありがちなサンプルコードを題材にしていく。
これを実行すると、str[2]はnullなので、NullPointerExceptionが投げ出される。
NullPointerExceptionはRuntimeExceptionのサブクラスであり、
RuntimeExceptionは、CatchしているExceptionのサブクラスのため、
NullPointerException発生⇒投げるぜ、RuntimeException⇒Catchするぜ、Exceptionという流れが可能になる。

例えばこの流れを崩したらどうなるだろうか?

いまはCatchにExceptionを指定しているが、ここを"SQLException"に変更すると、コンパイルエラーとなる。

Unreachable catch block for SQLException.

というエラーメッセージが出る。
SQLExceptionじゃ受け取れねーよ!というわけですな。


次に"throws"キーワードで指定している"RuntimeException"を"IOException"に変えてみる。
これだと普通に実行でき、実行時のコンソール内ではNullPointerExceptionをcatchしている様子が見れる。
ここで私の中で一つ疑問が、、、

メソッド呼び出し内で発生しているのはNullPointerExceptionだが、
別に継承関係にないIOExceptionをthrowsキーワードに指定しても普通に動くのはなぜか?
コンパイルエラーになりそうだと思っていたのだが、、、
ぐぐってみたらこんな記事を見つけた。

d.hatena.ne.jp

少し話題は逸れますが、ここで一つ確認しておきたいことが。Throwableが投げられる時、投げられ方には2種類ある。アプリケーションがthrow文で投げるケースと、JVMが投げるケース。

なるほど、つまり上記のケースでは、JVMNullPointerExceptionを投げていたということか。

さきほどのsampleFuncメソッドを下記のように書き換えると、
今度はIOExceptionを投げるようになり、catchするのもIOException。当然だけど。

	static void sampleFunc(String[] str) throws IOException{
		for(int i = 0; i < str.length; i++){
			System.out.println(str[i].toString());
			throw new IOException();
		}
	}

ここで、
catchキーワードをNullPointerExceptionに変えると、sampleFuncメソッド呼び出し箇所でコンパイルエラーとなる。

Unhandled type of Exception.

ふむふむ。

                    • -

再throwについて

一度キャッチした例外を再度throwする場合は、下記のようなコードとなる。
throwsキーワードで型指定ができるので、例えば"sampleFunc"メソッドのthrowキーワードを"RuntimeException"に書き換えると、
sampleFuncメソッド内の再throwしている箇所(throw e)にて、"Unhandled type of Exception."と怒られる。

public class TestException {

	static void sampleFunc(String[] str) throws IOException {
		try {
			for (int i = 0; i < str.length; i++) {
				sampleFunc2(str[i]);
			}
		} catch (IOException e) {
			System.out.println("Catch and throw...");
			throw e;
		}
	}

	static void sampleFunc2(String str2) throws IOException {
		System.out.println("Let's throw : IOEXception");
		throw new IOException();
	}

	public static void main(String[] args) {
		try {
			String[] str = new String[3];
			str[0] = "AAA";
			str[1] = "BBB";

			sampleFunc(str);
			System.out.println("try : ");
		} catch (Exception e) {
			System.out.println("catch a : " + e);
		} finally {
			System.out.println("Call a Fincally");
		}
	}
}
                  • -

multi-catchについて

try-catchブロックのcatchブロックにて、複数の例外オブジェクトをまとめてキャッチできる。
こんな感じで。

catch (IOException | NullPointerException e)

ちなみにこのmulti-catchでは、継承関係のある例外クラスは記述できない。
(IOException⇒Exceptionに書き換えると、"The Exception NullPointerException is already caught by the alternative Exception."と怒られる。)
また、multi-catchでキャッチした例外の参照変数は、final修飾子が付与されているとのこと。



今日は一旦ここまで。