finally句におけるreturnの問題

finally句でreturnしたコードを見かけることがあります。eclipseで開発している場合、finally句でreturnを記述すると警告が出るのですが何が問題なのかあまり知られていないようです。

  • try-finallyにおける様々の位置のreturnの検証

try-finallyでreturnする位置を変えて検証してみます。

①try句のreturn

public int method () throws Throwable {
	try {
		if (true) {
			throw new Exception("hoge");
		}
		return 0;
	} finally {
	}
}

methodは例外(hoge)がthrowされます。

②finally句のreturn

public int method () throws Throwable {
	try {
		if (true) {
			throw new Exception("hoge");
		}
	} finally {
		return 1;
	}
}

methodは正常終了し1が返されます。

③try-finally外のreturn

public int method () throws Throwable {
	try {
		if (true) {
			throw new Exception("hoge");
		}
	} finally {
	}
	return 2;
}

methodは例外(hoge)がthrowされます。

①③では例外発生した場合、method呼び出し元まで例外がthrowされるのですが、②のfinally句でreturnした場合は例外が握りつぶされるみたいです。このケースの場合ではおそらくコーダーは意図していないと思うのでバグの可能性が高いと思います。

ちなみに言語仕様では下記のようになっているようです。
tryブロックで中途完了、かつfinallyブロックで中途完了した場合はtryブロック中途完了理由は破棄され、finally中途完了理由となる。
中途完了とはreturn, break, throwを指すようです。

②は論外として一般的にデグレが起きにくいコーディングを考えると③が妥当なんでしょうかね?