Rumah  >  Artikel  >  Java  >  Apakah perintah pelaksanaan pemulangan dan akhirnya pernyataan di Jawa?

Apakah perintah pelaksanaan pemulangan dan akhirnya pernyataan di Jawa?

PHPz
PHPzke hadapan
2023-04-25 19:55:061875semak imbas

Kod sumber:

public class ReturnFinallyDemo {     public static void main(String[] args) {         System.out.println(case1());     }      public static int case1() {         int x;         try {             x = 1;             return x;         } finally {             x = 3;         }     } }  # 输出

Keluaran kod di atas boleh membuat kesimpulan bahawa pemulangan dilaksanakan sebelum akhirnya. Yang berikut memintas sebahagian kod bait kaedah case1 dan membandingkannya dengan kod sumber untuk menganotasi maksud setiap arahan:

iconst_1 // 将常量1推入操作数栈顶  istore_0 // 弹出栈顶元素(1),保存到局部变量表slot[0],此时slot[0]=1。这两条指令对应源码:x = 1;  iload_0 // 将局部变量表slot[0]的值推入操作数栈顶,也就是说把上面x的值推入栈顶  istore_1 // 弹出栈顶元素(1),保存到局部变量表slot[1],此时slot[1]=1。其实,此时就已经把要return的值准备好了  iconst_3 // 将常量3推入操作数栈顶,这一条指令开始,其实是开始执行finally中的代码了  istore_0 // 弹出栈顶元素(3),保存到局部变量表slot[0],此时slot[0]=3。这两个指令对应源码:x = 3;这里要注意的是,虽然都是更新了x的值,但是finally中的x和try中x的赋值,保存在了不同的局部变量表中 iload_1 // 将局部变量表slot[1]的值推入操作数栈顶,此时栈顶元素的值为1,是第3行指令保存的值  ireturn // 将操作数栈顶的值返回给调用方

Daripada kod bait, nampaknya kod akhirnya dilaksanakan terlebih dahulu. Oleh kerana arahan ireturn memang dilaksanakan pada penghujungnya, nilai yang dikembalikan tidak bergantung pada siapa yang melaksanakannya dahulu, tetapi apabila elemen teratas timbunan operan yang dikembalikan oleh arahan ireturn disimpan. Dalam persekitaran kod di atas, ia adalah versi yang diberikan kepada x dalam blok kod cuba, iaitu versi x disimpan serta-merta selepas penyata pulangan.

Mari kita lihat senario yang lebih rumit:

public static int case2() {     int x;     try {         x = 1;         return ++x;     } finally {         x = 3;     } }  # 输出

Dengan analisis di atas, ini mudah difahami Mari kita lihat kod bait:

iconst_1 // 将常量1推入操作数栈顶 istore_0 // 弹出栈顶元素(1),保存到局部变量表slot[0],此时slot[0]=1。这两条指令对应源码:x = 1; iinc          0, 1 // 对局部变量表slot[0]进行自增(+1)操作,此时slot[0]=2,对应源码:++x;所以,可以看出return后面的表达式先执行 iload_0 // 将局部变量表slot[0]的值推入操作数栈顶,也就是说把上面x的值(2)推入栈顶 istore_1 // 弹出栈顶元素(2),保存到局部变量表slot[1],此时slot[1]=2。其实,此时就已经把要return的值准备好了 iconst_3 // 将常量3推入操作数栈顶,这一条指令开始,其实是开始执行finally中的代码了 istore_0 // 弹出栈顶元素(3),保存到局部变量表slot[0],此时slot[0]=3。这两个指令对应源码:x = 3;这里要注意的是,虽然都是更新了x的值,但是finally中的x和try中x的赋值,保存在了不同的局部变量表中 iload_1 // 将局部变量表slot[1]的值推入操作数栈顶,此时栈顶元素的值为2,是第6行指令保存的值,也就是经过++x之后的值 ireturn // 将操作数栈顶的值返回给调用方

Seperti yang dapat dilihat dari kod di atas, arahan selepas pemulangan dilaksanakan terlebih dahulu, kemudian disimpan ke jadual pembolehubah tempatan, kemudian penyataan dalam akhirnya dilaksanakan, dan akhirnya arahan pemulangan itu sendiri dilaksanakan.

Untuk meringkaskan, arahan pemulangan dilaksanakan terakhir Jika terdapat ungkapan selepas pemulangan, penyataan dalam akhirnya akan dilaksanakan selepas ungkapan itu dilaksanakan, dan arahan pemulangan akan dilaksanakan terakhir. Jadi yang mana satu dilaksanakan dahulu, akhirnya atau kembali: jika terdapat ungkapan atau panggilan kaedah selepas arahan pulangan, ia akan dilaksanakan terlebih dahulu, kemudian akhirnya, dan akhirnya arahan kembali. Sama seperti hasil demonstrasi program di atas, hasil pulangan akhir tidak boleh dinilai hanya dari tugasan x Dari peringkat arahan, kedua-dua tugasan kepada x disimpan di lokasi yang berbeza dalam jadual pembolehubah setempat.

Akhirnya, mari kita lihat senario yang biasanya tidak ditulis seperti ini:

public static int case3() {     int x;     try {         x = 1;         return ++x;     } finally {         x = 3;         return x;     } } # 输出

Ini adalah contoh akhirnya mengembalikan hasil. Kami juga tidak disyorkan mulakan dari bytecode Mari analisanya dari perspektif:

iconst_1 // 将常量1推入操作数栈顶 istore_0 // 弹出栈顶元素(1),保存到局部变量表slot[0],此时slot[0]=1。这两条指令对应源码:x = 1; iinc          0, 1 // 对局部变量表slot[0]进行自增(+1)操作,此时slot[0]=2,对应源码:++x;所以,可以看出return后面的表达式先执行 iload_0  // 将局部变量表slot[0]的值推入操作数栈顶,也就是说把上面x的值(2)推入栈顶 istore_1 // 弹出栈顶元素(2),保存到局部变量表slot[1],此时slot[1]=2。 iconst_3 // 将常量3推入操作数栈顶,这一条指令开始,其实是开始执行finally中的代码了 istore_0 // 弹出栈顶元素(3),保存到变量表slot[0],此时slot[0]=3。这两个指令对应源码:x = 3 iload_0  // 将局部变量表slot[0]的值(3)推入操作数栈,这是跟之前不一样的地方,ireturn返回的值选择的局部变量表不一样 ireturn

Atas ialah kandungan terperinci Apakah perintah pelaksanaan pemulangan dan akhirnya pernyataan di Jawa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam