Javaメソッドがスタックフレームで行われ、スタックフレームは、メソッドを実行する方法としてメモリ空間の各々に割り当てられるスレッドのプライベートスタック部、小さなスタック領域の実行方法のスレッドで、スタックフレームは、3つの領域に分割されています:
オペランドスタックは、実行中の式のオペランドを保存するために使用されている1、多項式評価のデータ構造としてスタックアルゴリズム、オペランドスタックと役割に基づいて学習しました
2.ローカル変数は、方法で使用される変数の保存、パラメータを含む方法は、変数は内部メソッド、メンバ変数とメソッドまたはクラスオブジェクト(静的変数)に使用されるメンバ変数、最後の2つの変数を宣言しましたローカル変数にコピーされたので、マルチスレッド環境では、この変数は、必要に応じて揮発性の型として宣言する必要があります
3.バイトコード命令領域、これを説明していない、命令コード内のメソッドが翻訳されます
return文
finallyブロックせずに実装return文。次のように今度は、return文のreturn文の形式を見てみましょうすることです:
return [expression];
前記いくつかの方法は値を返さないため、式(式)は、任意であるので、そこには、リターンバック発現されず、又は発現は、空のように見ることができます。
私たちは、彼の復帰はそれのどこ値であるので、return文の役割は、メソッドを締結し、値を返すことが知っていますか?戻り値のリターン命令実行時間を、オペランドスタックの値が、式で表現の種類に関係なく、それはリターン命令のために重要なのは、仕事を何がない行っている、彼はスタックのオペランドトップのための唯一の責任があります値が返されます。return式が実施された2つの部分に分かれています。
执行:expression;
执行:return指令;
たとえば、次のリターンX + Y;このコードは、x + yおよびその後の復帰を行うことを実行するために、X + Y、X及びYは、第1オペランドスタック命令のローカル変数にコピーから実行され、その後、加算が実行され、このとき結果値は、スタックのオペランドスタックに格納され、最終的にはリターン命令、オペランドスタックの戻り値を実行します。
リターンxに対して、X最初の実装、xは、一つだけのオペランドを有する式で変数xがオペランドスタック命令にローカル変数からコピーされて実行し、リターン実行、リターンのオペランドスタック値。したがって、X戻り、実際のリターンリターン命令が実行されると、スタックのスナップショットまたはコピーのオペランドxはむしろ値Xより、と呼ばれています。
finallyブロック:
あなたが最終的にブロックする方法を持っている場合は、return文は、それを実装する方法ですか?次のコード例:
try {
return expression;
} finally {
do some work;
}
まず、私たちが知っているすべての、最終的には文が実行されますが、その実行順序は、どのようにそれのようなものでしょうか?次のように実行の順序である:
1を実行:.発現、発現は、結果はオペランドスタックに格納されて評価されます。
図2は、実行:戻り値としてローカル変数にスタックオペランド(式の結果)の上部と、
実行3.:最後に、コード文をブロックします。
4.実行:ローカル変数とオペランドスタックのコピーバックの戻り値の第二のステップをコピーします。
5.実行:リターン命令、オペランドスタックの戻り値を、
私たちは、最初のステップが終了するには、全体のプロセスの戻り値が確認されていることを確認するだけでなく、finallyブロックが実行さによることができ、プログラムは一時的にローカル変数に格納されている値を返します、オペランドスタックを作るために使用されていますfinally文の実行コードのブロック、そして最終的に完成し、オペランドスタックの戻り値に一時的に保存され、コピーバックのような。だから、最終的には戻り値は無益であるブロック変更しようとする試みは、finallyブロックを実行するには、どのような操作に関係なく、それは戻り値に影響を与えることができないので。だから、最終的には文ブロックは、単にいくつかの重要な最後の仕上げを行うための方法を取得するために設計されており、戻り値を計算するのに使用されていません。
サンプルコード:
public class FinallyDemo {
public int testMethod(String _int,String _className){
int x = 1;
try{
Integer.valueOf(_int);
Class.forName(_className);
//如果上面两句代码没有发生异常,对于return x这句代码,程序会先计算表达式x
//即将x从局部变量区复制到操作数栈顶,结果就是操作数栈顶的值,也就是x的值,为1
//然后将操作数栈顶的值复制到局部变量区(假设这个复制到局部变量区的值叫returnvalue),再执行finally代码块,在finally代码块
//中,x的值被修改为3(即局部变量区中的x值),finally执行完,程序又将returnvalue复制到操作数栈顶,然后执行return指令,返回
//操作数栈顶的值,最终返回值是1
return x;
}catch(ClassNotFoundException e){
//同样发生了ClassNotFoundException,x的值被修改成2
//因此在catch中的return x语句中定义了返回值大小为2,所以最终返回的是2
x = 2;
return x;
}finally{
//这句代码一定会执行的,这里的代码执行结束后才会结束方法并返回值,因此在finally语句修改x不会影响返回值,因为返回值在return 后面的
//表达式执行完就已经确定了,他是x的快照,而不是x
x = 3;
}
}
public static void main(String [] args){
try{
FinallyDemo demo = new FinallyDemo();
int i_1 = demo.testMethod("123123", "expert.in.java.lang.CalendarDemo");
System.out.println(i_1);//结果为1
int i_2 = demo.testMethod("123123", "com.edu.cn.qj.MyClass");
System.out.println(i_2);//结果为2
int i_3 = demo.testMethod("dsadf", "expert.in.java.lang.CalendarDemo");
System.out.println(i_3);//没有返回值,会抛出异常
}finally{
}
}
}