Perbezaan Antara Akhir, Akhir dan Akhir di Jawa

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat gambaran keseluruhan tiga kata kunci Java: final, akhirnya dan final.

Walaupun kata kunci ini mirip satu sama lain masing-masing mempunyai makna yang sangat berbeza di Jawa. Kami akan mengetahui tujuan masing-masing dan melihat beberapa contoh melalui sedikit kod.

2. Kata kunci akhir

Mari kita perhatikan kata kunci terakhir , di mana menggunakannya dan mengapa. Kita boleh menerapkan kata kunci terakhir pada pernyataan parameter kelas, kaedah, medan, pemboleh ubah dan kaedah.

Ia tidak mempunyai kesan yang sama pada masing-masing :

  • Membuat kelas akhir bermaksud tidak boleh melanjutkan kelas itu
  • Menambah akhir ke kaedah bermaksud bahawa kaedah tidak boleh diganti
  • Akhirnya, meletakkan akhir di depan bidang, pemboleh ubah atau parameter bermaksud bahawa setelah rujukan diberikan maka tidak dapat diubah (namun, jika rujukannya ke objek yang dapat diubah, keadaan dalamannya dapat berubah walaupun sudah final)

Artikel terperinci mengenai kata kunci akhir boleh didapati di sini.

Mari lihat bagaimana kata kunci akhir berfungsi melalui beberapa contoh.

2.1. akhir Fields, Parameter dan Pembolehubah

Mari buat kelas Ibu Bapa dengan dua medan int , yang terakhir , dan yang bukan akhir yang biasa:

public class Parent { int field1 = 1; final int field2 = 2; Parent() { field1 = 2; // OK field2 = 3; // Compilation error } }

Seperti yang kita lihat, penyusun melarang kita memberikan nilai baru ke bidang2 .

Mari sekarang tambahkan kaedah dengan argumen biasa dan terakhir:

 void method1(int arg1, final int arg2) { arg1 = 2; // OK arg2 = 3; // Compilation error }

Begitu juga dengan bidang, tidak mungkin menetapkan sesuatu ke arg2 kerana dinyatakan sebagai akhir.

Kita sekarang boleh menambahkan kaedah kedua untuk menggambarkan bagaimana ini berfungsi dengan pemboleh ubah tempatan:

 void method2() { final int localVar = 2; // OK localVar = 3; // Compilation error }

Tidak ada yang mengejutkan yang berlaku, penyusun tidak membiarkan kami memberikan nilai baru kepada localVar selepas penugasan pertama.

2.2. Kaedah akhir

Sekarang andaikan kita menjadikan kaedah 2 akhir dan membuat subkelas Parent , katakanlah Child , di mana kita cuba mengatasi kedua-dua kaedah superclassnya:

public class Child extends Parent { @Override void method1(int arg1, int arg2) { // OK } @Override final void method2() { // Compilation error } }

Seperti yang dapat kita lihat, tidak ada masalah dengan kaedah overriding1 () , tetapi kita mendapat ralat kompilasi ketika cuba mengganti kaedah2 () .

2.3. Kelas akhir

Dan akhirnya, mari kita buat kelas Anak akhir dan cuba buat subkelasnya, GrandChild :

public final class Child extends Parent { // ... }
public class GrandChild extends Child { // Compilation error }

Sekali lagi, penyusun mengeluh. Kelas Kanak - kanak adalah muktamad dan oleh itu mustahil untuk dilanjutkan.

3. akhirnya Sekat

Yang akhirnya blok blok pilihan untuk menggunakan dengan percubaan / tawanan kenyataan. Di blok ini, kami memasukkan kod untuk dilaksanakan setelah struktur cubaan / tangkapan , sama ada pengecualian dilemparkan atau tidak .

Bahkan mungkin untuk menggunakannya dengan blok cubaan tanpa blok tangkapan dengan syarat kami menyertakan blok akhirnya . Kod kemudian akan dilaksanakan setelah percubaan atau setelah pengecualian dilemparkan.

Kami memiliki artikel mendalam tentang pengendalian pengecualian di Jawa di sini.

Sekarang mari kita menunjukkan blok akhirnya dalam contoh pendek. Kami akan membuat kaedah main () dummy dengan struktur try / catch / akhirnya :

public static void main(String args[]) { try { System.out.println("Execute try block"); throw new Exception(); } catch (Exception e) { System.out.println("Execute catch block"); } finally { System.out.println("Execute finally block"); } }

Sekiranya kita menjalankan kod ini, ia akan mengeluarkan yang berikut:

Execute try block Execute catch block Execute finally block

Sekarang mari kita ubah kaedah dengan membuang blok tangkapan (dan tambahkan pengecualian lemparan ke tandatangan):

public static void main(String args[]) throws Exception { try { System.out.println("Execute try block"); throw new Exception(); } finally { System.out.println("Execute finally block"); } }

Keluarannya sekarang:

Execute try block Execute finally block

Jika kita sekarang membuang arahan lontaran Exception () baru , kita dapat melihat bahawa outputnya tetap sama. Pelaksanaan sekatan akhirnya kami berlaku setiap masa.

4. menyelesaikan Kaedah

Dan akhirnya, kaedah akhir adalah kaedah terlindung, yang ditentukan dalam kelas Objek. Ia dipanggil oleh pengutip sampah pada objek yang tidak dirujuk lagi dan telah dipilih untuk pengumpulan sampah .

Seperti kaedah bukan akhir yang lain, kita boleh mengatasi kaedah ini untuk menentukan tingkah laku yang mesti dimiliki oleh objek ketika dikumpulkan oleh pengumpul sampah .

Sekali lagi, artikel terperinci yang merangkumi kaedah menyelesaikan boleh didapati di sini.

Mari lihat contoh bagaimana ia berfungsi. Kami akan menggunakan System.gc () untuk mencadangkan JVM untuk mencetuskan pengumpulan sampah :

 @Override protected void finalize() throws Throwable { System.out.println("Execute finalize method"); super.finalize(); }
 public static void main(String[] args) throws Exception { FinalizeObject object = new FinalizeObject(); object = null; System.gc(); Thread.sleep(1000); }

Dalam contoh ini, kita mengesampingkan kaedah finalize () dalam objek kita dan membuat kaedah utama () yang memberi contoh objek kita dan segera menjatuhkan rujukan dengan menetapkan pemboleh ubah yang dibuat menjadi null .

After that, we call System.gc() to run the garbage collector (at least we expect it to run) and wait for a second (just to ensure that the JVM doesn't shut down before garbage collector has the chance to call finalize() method).

The output of this code execution should be:

Execute finalize method

Note that it's considered bad practice to override finalize() method as its execution depends on garbage collection which is in the hand of the JVM. Plus, this method has been deprecated since Java 9.

5. Conclusion

Dalam artikel ini, kami telah membincangkan secara ringkas perbezaan antara tiga kata kunci sama Java: final, akhirnya dan final .

Kod lengkap artikel boleh didapati di GitHub.