finally浅談

3537 ワード

最近プログラムをする時突発的に奇想天外です:try...finally ... のfinallyは、戻る前に実行します(XXXの本で见た、タイトルを忘れました)、以下のテストを行いました

public class FinallyTest 
{
	public static void main(String args[])
	{
		System.out.println("return: " + new FinallyTest().getString());
	}
	
	public String getString()
	{
		String returnString = null;
		try
		{
			returnString = "this string will be return.";
			return returnString;		
		}finally
		{			
			System.out.println("execute finally...");
			System.out.println("before clean returnString's value: " + returnString);
			returnString = null;
			System.out.println("after  clean returnString's value: " + returnString);
			System.out.println("execute finally end.");
		}		
	}
}

テストの締めくくり:

execute finally...
before clean returnString's value: this string will be return.
after  clean returnString's value: null
execute finally end.
return: this string will be return.

戻る前に実行する場合は、返される文字列は空である必要があります.しかし、結果から見ると、予想外のようだ.
理由:戻る前に返された結果をコピーしました.
そこで以下の修正を行いました.

public class FinallyTest 
{
	public static void main(String args[])
	{
		System.out.println("return: " + new FinallyTest().getMessage().message);
	}
	
	public Message getMessage()
	{
		Message returnMessage = new Message();
		try
		{
			returnMessage.message = "message";
			return returnMessage;		
		}finally
		{			
			System.out.println("execute finally...");
			System.out.println("before clean returnString's value: " + returnMessage.message);
			returnMessage.message = null;
			System.out.println("after  clean returnString's value: " + returnMessage.message);
			System.out.println("execute finally end.");
		}		
	}
}

class Message
{
	public String message = "message";
}

結果:

execute finally...
before clean returnString's value: message
after  clean returnString's value: null
execute finally end.
return: null

結果として、オブジェクトの参照のみが呼び出され、オブジェクトはコピーされません.
一般的なデータ型をfinallyで統一的に処理するのは避けたほうがいいようだ.

public class FinallyTest 
{
	public static void main(String args[])
	{
		System.out.println("return: " + new FinallyTest().getInt());
	}
	
	public int getInt()
	{
		int returnInt = 0;
		try
		{
			returnInt = 1;
			throw new RuntimeException("...");
		}catch(Exception e)
		{
			returnInt = 2;
			return returnInt;
		}finally
		{			
			System.out.println("execute finally...");
			System.out.println("before switch returnInt's value: " + returnInt);
			switch(returnInt)
			{
				case 1:
					returnInt = 0;
					break;
				case 2:
					returnInt = 3;
					break;
				default:
					returnInt = 4;
			}
			System.out.println("after  switch returnInt's value: " + returnInt);
			System.out.println("execute finally end.");
		}		
	}
}