Perbedaan Antara Final, Akhirnya dan Finalisasi di Java

1. Ikhtisar

Dalam tutorial ini, kita akan mengambil ikhtisar dari tiga kata kunci Java: final, akhirnya, dan finalize.

Sedangkan kata kunci tersebut mirip satu sama lain masing-masing memiliki arti yang sangat berbeda di Jawa. Kami akan mempelajari tujuan masing-masing dan melihat beberapa contoh melalui sedikit kode.

2. Kata Kunci akhir

Pertama-tama, mari kita lihat kata kunci terakhir , di mana menggunakannya dan mengapa. Kita dapat menerapkan kata kunci terakhir ke deklarasi parameter class, method, field, variabel dan method.

Itu tidak memiliki efek yang sama pada masing-masing :

  • Membuat kelas final berarti tidak mungkin untuk memperpanjang kelas itu
  • Menambahkan final ke metode berarti tidak mungkin mengganti metode itu
  • Akhirnya, meletakkan final di depan bidang, variabel atau parameter berarti bahwa setelah referensi ditetapkan maka itu tidak dapat diubah (namun, jika referensi ke objek yang bisa berubah, status internalnya dapat berubah meskipun final)

Artikel rinci tentang kata kunci terakhir dapat ditemukan di sini.

Mari kita lihat bagaimana kata kunci terakhir bekerja melalui beberapa contoh.

2.1. Field akhir , Parameter, dan Variabel

Mari buat kelas Parent dengan dua bidang int , yang terakhir , dan yang biasa non-final:

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

Seperti yang bisa kita lihat, kompilator melarang kita untuk memberikan nilai baru ke bidang2 .

Sekarang mari tambahkan metode dengan argumen reguler dan terakhir:

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

Sama halnya dengan bidang, tidak mungkin menetapkan sesuatu ke arg2 karena dinyatakan final.

Sekarang kita dapat menambahkan metode kedua untuk menggambarkan bagaimana ini bekerja dengan variabel lokal:

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

Tidak ada yang mengejutkan terjadi, kompilator tidak mengizinkan kita memberikan nilai baru ke localVar setelah penetapan pertamanya.

2.2. Metode terakhir

Sekarang misalkan kita membuat method2 final dan membuat subclass Parent , katakanlah Child , di mana kita mencoba menimpa kedua metode superclassnya:

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

Seperti yang bisa kita lihat, tidak ada masalah dengan menimpa method1 () , tetapi kita mendapatkan kesalahan kompilasi saat mencoba menimpa method2 () .

2.3. Kelas terakhir

Dan terakhir, mari kita buat kelas Anak menjadi final dan coba buat subkelasnya, GrandChild :

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

Sekali lagi, kompilator mengeluh. Kelas Anak bersifat final dan oleh karena itu tidak mungkin untuk diperpanjang.

3. akhirnya Blokir

The akhirnya blok blok opsional untuk digunakan dengan mencoba / menangkap pernyataan. Di blok ini, kami menyertakan kode untuk dieksekusi setelah struktur coba / tangkap , apakah pengecualian dilemparkan atau tidak .

Bahkan dimungkinkan untuk menggunakannya dengan blok coba tanpa blok tangkap apa pun asalkan kami menyertakan blok akhirnya . Kode kemudian akan dijalankan setelah percobaan atau setelah pengecualian dilemparkan.

Kami memiliki artikel mendalam tentang penanganan pengecualian di Java di sini.

Sekarang mari kita tunjukkan blok terakhir dalam contoh singkat. Kami akan membuat metode dummy main () dengan struktur coba / tangkap / 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"); } }

Jika kita menjalankan kode ini, itu akan menghasilkan yang berikut:

Execute try block Execute catch block Execute finally block

Sekarang mari kita memodifikasi metode dengan menghapus blok catch (dan menambahkan Exception ke tanda tangan):

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"); } }

Outputnya sekarang:

Execute try block Execute finally block

Jika sekarang kita menghapus instruksi throw new Exception () , kita dapat mengamati bahwa outputnya tetap sama. Eksekusi blok kami akhirnya terjadi setiap saat.

4. menyelesaikan Metode

Dan terakhir, metode finalisasi adalah metode yang dilindungi, yang didefinisikan di kelas Object. Ini dipanggil oleh pengumpul sampah pada objek yang tidak dirujuk lagi dan telah dipilih untuk pengumpulan sampah .

Like any other non-final method we can override this method to define the behavior an object must have when collected by the garbage collector.

Again, a detailed article covering the finalize method can be found here.

Let's see an example of how it works. We'll use System.gc() to suggest the JVM to trigger garbage collection:

 @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); }

In this example, we override finalize() method in our object and create a main() method which instantiates our object and immediately drops the reference by setting the created variable to 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

Pada artikel ini, kami telah membahas secara singkat perbedaan antara tiga kata kunci yang mirip Java: final, akhirnya, dan finalize .

Kode lengkap artikel dapat ditemukan di GitHub.