パズル36-パズル

4218 ワード

パズル36:優柔不断
public class Main36 {
	public static void main(String[] args) {
		System.out.println(decision()); //false
	}
	private static boolean decision() {
		try{
			return true;
		}
		finally{
			return false;
		}
	}
}

理由:try-finally文では、finallyは常にtry文ブロックから制御権が離れるときに実行されます.try文ブロックが正常に終了しても予期せぬ終了しても、状況は同じです.
要するに、finally文ブロックをreturn、break、continue、またはthrowで終了しないでください.また、チェックされた例外をfinally文ブロックの外に伝播させないでください.
パズル37:不思議極まりない
まず次の3つのプログラムを見て、何が印刷されますか?
public class Main1 {

	public static void main(String[] args) {
		 try {
		  System.out.println("Hello world");
		 } catch (IOException e) {
		 System.out.println("I've never seen println fail!");
		 }}}
public class Main2 {

	public static void main(String[] args) {
		 try {
		 //if you have nothing nice to say,say nothing.
		 } catch (Exception e) {
		 System.out.println("This can't happen!");
		 }}}
import java.io.IOException;
interface Type1 {
	void f() throws CloneNotSupportedException;
}
interface Type2 {
	void f() throws InterruptedException;
}
interface Type3 extends Type1, Type2 {

}
public class Main37 implements Type3 {

	public static void main(String[] args) {
		Type3 t3 = new Main37();
		t3.f();// Hello world
	}
	@Override
	public void f() {
		System.out.println("Hello world");
	}
}

最初のプログラムはコンパイルされますが、printlnメソッドではチェック対象の例外が放出されると宣言されていません.IOExceptionはチェック対象の例外です.言語仕様では、catch文がEのタイプのチェック対象の例外をキャプチャし、対応するtry文がEのサブタイプの例外を放出できない場合、これがコンパイルエラーです.
2つ目はコンパイルできますが、何も印刷されません.ExceptionまたはThrowableをキャプチャするcatch句は、対応するtry句の内容にかかわらず合法です.
3つ目はコンパイルもできますが、
1つの方法では、チェック対象例外の集合を放出するときに適用されるすべてのタイプが、集合ではなく、放出するチェック対象例外の交差を宣言します.したがって,静的タイプがType 3のオブジェクト上のメソッドfは異常を投げ出すことはない.
パズル38:モテないお客様
public class Main38 {

	public static final long GUEST_USER_ID = -1;
	private static final long USER_ID;
	static {
		try {
			USER_ID = getUserIdFromEnvironment();
		} catch (IdUnavailableException e) {
			USER_ID = GUEST_USER_ID;
		}
	}

	public static void main(String[] args) {

		System.out.println("User ID: " + USER_ID);
	}

	private static long getUserIdFromEnvironment()
			throws IdUnavailableException {
		throw new IdUnavailableException();
	}

}

このプログラムはコンパイルできません.1つのプログラムが1つの空finalに対して1回以上値を付与できるかどうかを決定するのは難しい問題ですが、実際には不可能です.空のfinalドメインは、実際に値が割り当てられていない場所でのみ値を割り当てることができます.
こんにちは、さようなら
public class Main39 {
	public static void main(String[] args) {
		try {
			System.out.println("hello world!");
			System.exit(0);
		}
		finally{
			System.out.println("goodbye world!");
		}
	}
}
hello worldのみ印刷!
try文ブロックの実行が正常に終了しても、意外に終了しても、finally文ブロックは実行されます.しかしながら、このプログラムではtry文ブロックは実行プロセスを終了しない.System.exitメソッドは、現在のスレッドと他のすべてのその場で死亡したスレッドを停止します.finally句の出現はスレッドの継続実行に特別な権限を与えることができない.
パズル40:望ましくないコンストラクタ
public class Reluctant {

	private Reluctant internalInstance = new Reluctant();
	public Reluctant() throws Exception{
		throw new Exception("I'm not coming out!");
	}
	
	public static void main(String[] args) {
		try {
			Reluctant b = new Reluctant();
			System.out.println("Surprise!");
		} catch (Exception e) {
			System.out.println("I told you so");
		}
	}
}

javaが投げ出されます.lang.StackOverflowError異常.ほとんどのjavaを投げ出す.lang.StackOverflowError異常のプログラムサンプルプログラムにも無限再帰が含まれています.コンストラクタを呼び出すと、インスタンス変数の初期化操作はコンストラクタのプログラム体よりも先に実行されます.なぜならjava.lang.StackOverflowErrorはExceptionのサブタイプではなくErrorのサブタイプなので
mainのcatch句はスナップできません.コンストラクタは、インスタンスの初期化操作によって放出されるすべてのチェック対象例外を宣言する必要があります.