Masa Pakai Objek: Bagaimana Objek Dibuat dan Dihancurkan (Visual Basic)
Instans kelas, objek, dibuat dengan menggunakan kata kunci New
. Tugas inisialisasi sering kali harus dilakukan pada objek baru sebelum digunakan. Tugas inisialisasi umum termasuk membuka file, menyambungkan ke database, dan membaca nilai kunci registri. Visual Basic mengontrol inisialisasi objek baru menggunakan prosedur yang disebut konstruktor (metode khusus yang memungkinkan kontrol pada inisialisasi).
Setelah objek meninggalkan cakupan, objek dirilis oleh runtime bahasa umum (CLR). Visual Basic mengontrol rilis sumber daya sistem menggunakan prosedur yang disebut destruktor. Bersama-sama, konstruktor dan destruktor mendukung pembuatan pustaka kelas yang kuat dan dapat diprediksi.
Menggunakan Konstruktor dan Destruktor
Konstruktor dan destruktor mengontrol pembuatan dan penghancuran objek. Prosedur Sub New
dan Sub Finalize
dalam Visual Basic menginisialisasi dan menghancurkan objek; mereka menggantikan metode Class_Initialize
dan Class_Terminate
yang digunakan dalam Visual Basic 6.0 dan versi yang lebih lama.
Sub Baru
Konstruktor Sub New
hanya dapat berjalan sekali ketika kelas dibuat. Konstruktor tersebut tidak dapat dipanggil secara eksplisit dari mana saja selain di baris kode pertama konstruktor lain baik di kelas yang sama atau kelas turunan. Selain itu, kode dalam metode Sub New
selalu berjalan sebelum kode lain di kelas. Visual Basic secara implisit membuat konstruktor Sub New
pada durasi jika Anda tidak secara eksplisit menentukan prosedur Sub New
untuk kelas.
Untuk membuat konstruktor untuk kelas, buat prosedur bernama Sub New
di mana saja dalam penentuan kelas. Untuk membuat konstruktor berparameter, tentukan nama dan jenis data argumen menjadi Sub New
sama seperti Anda akan menentukan argumen untuk prosedur lain, seperti dalam kode berikut:
Sub New(ByVal s As String)
Konstruktor sering kelebihan beban, seperti dalam kode berikut:
Sub New(ByVal s As String, i As Integer)
Ketika Anda menentukan kelas yang berasal dari kelas lain, baris pertama konstruktor harus berupa panggilan ke konstruktor kelas dasar, kecuali kelas dasar memiliki konstruktor yang dapat diakses yang tidak memerlukan parameter. Panggilan ke kelas dasar yang berisi konstruktor di atas, misalnya, adalah MyBase.New(s)
. Jika tidak, MyBase.New
bersifat opsional, dan runtime Visual Basic memanggilnya secara implisit.
Setelah Anda menulis kode untuk memanggil konstruktor objek induk, Anda dapat menambahkan kode inisialisasi tambahan ke prosedur Sub New
. Sub New
dapat menerima argumen ketika dipanggil sebagai konstruktor berparameter. Parameter ini diteruskan dari prosedur yang memanggil konstruktor, misalnya, Dim AnObject As New ThisClass(X)
.
Sub-Finalisasi
Sebelum merilis objek, CLR secara otomatis memanggil metode Finalize
untuk objek yang menentukan prosedur Sub Finalize
. Metode Finalize
ini dapat berisi kode yang perlu dijalankan tepat sebelum objek dihancurkan, seperti kode untuk menutup file dan menyimpan informasi status. Ada sedikit penalti performa untuk mengeksekusi Sub Finalize
, jadi Anda harus menentukan metode Sub Finalize
hanya ketika Anda perlu merilis objek secara eksplisit.
Catatan
Pengumpul sampah di CLR tidak (dan tidak dapat) membuang objek yang tidak dikelola, objek yang dijalankan sistem operasi secara langsung, di luar lingkungan CLR. Ini karena objek yang tidak dikelola yang berbeda harus dibuang dengan cara yang berbeda. Informasi tersebut tidak terkait langsung dengan objek yang tidak dikelola; informasi tersebut harus ditemukan dalam dokumentasi untuk objek. Kelas yang menggunakan objek yang tidak dikelola harus membuangnya dalam metode Finalize
.
Destruktor Finalize
adalah metode terlindungi yang hanya dapat dipanggil dari kelas miliknya, atau dari kelas turunan. Sistem memanggil Finalize
secara otomatis ketika objek dihancurkan, jadi Anda tidak boleh secara eksplisit memanggil Finalize
dari luar implementasi Finalize
kelas turunan.
Tidak seperti Class_Terminate
, yang dijalankan segera setelah objek tidak diatur ke apapun, biasanya ada penundaan antara ketika objek kehilangan cakupan dan ketika Visual Basic memanggil destruktor Finalize
. Visual Basic .NET memungkinkan jenis destruktor kedua, IDisposable.Dispose, yang dapat secara eksplisit dipanggil kapan saja untuk segera merilis sumber daya.
Catatan
Destruktor Finalize
tidak boleh melemparkan pengecualian, karena tidak dapat ditangani oleh aplikasi dan dapat menyebabkan aplikasi dihentikan.
Cara Kerja Metode Baru dan Finalisasi dalam Hierarki Kelas
Setiap kali instans kelas dibuat, runtime bahasa umum (CLR) mencoba menjalankan prosedur bernama New
, jika ada di objek tersebut. New
adalah jenis prosedur yang disebut constructor
yang digunakan untuk menginisialisasi objek baru sebelum kode lain dalam objek dijalankan. Konstruktor New
dapat digunakan untuk membuka file, menyambungkan ke database, menginisialisasi variabel, dan mengurus tugas lain yang perlu dilakukan sebelum objek dapat digunakan.
Ketika instans kelas turunan dibuat, konstruktor Sub New
kelas dasar dijalankan terlebih dahulu, diikuti dengan konstruktor di kelas turunan. Ini terjadi karena baris pertama kode dalam konstruktor Sub New
menggunakan sintaks MyBase.New()
untuk memanggil konstruktor kelas tepat di atas dirinya sendiri dalam hierarki kelas. Konstruktor Sub New
kemudian dipanggil untuk setiap kelas dalam hierarki kelas sampai konstruktor untuk kelas dasar tercapai. Pada saat itu, kode dalam konstruktor untuk kelas dasar dijalankan, diikuti oleh kode di setiap konstruktor di semua kelas turunan dan kode di kelas yang paling diturunkan dijalankan terakhir.
Ketika objek tidak lagi diperlukan, CLR memanggil metodeFinalize untuk objek tersebut sebelum membebaskan memorinya. Metode Finalize ini disebut destructor
karena melakukan tugas pembersihan, seperti menyimpan informasi status, menutup file dan koneksi ke database, dan tugas lain yang harus dilakukan sebelum merilis objek.
Antarmuka IDisposable
Instans kelas sering mengontrol sumber daya yang tidak dikelola oleh CLR, seperti handel Windows dan koneksi database. Sumber daya ini harus dibuang dalam metode Finalize
kelas, sehingga mereka akan dilepaskan ketika objek dihancurkan oleh pengumpul sampah. Namun, pengumpul sampah menghancurkan objek hanya ketika CLR membutuhkan lebih banyak memori bebas. Ini berarti bahwa sumber daya bisa tidak dirilis hingga lama setelah objek keluar dari cakupan.
Untuk melengkapi pengumpulan sampah, kelas Anda dapat menyediakan mekanisme untuk mengelola sumber daya sistem secara aktif jika mereka mengimplementasikan antarmuka IDisposable. IDisposable memiliki satu metode, Dispose, yang harus dipanggil klien ketika mereka selesai menggunakan objek. Anda dapat menggunakan metode Dispose untuk segera merilis sumber daya dan melakukan tugas seperti menutup file dan koneksi database. Tidak seperti destruktor Finalize
, metode Dispose tidak dipanggil secara otomatis. Klien kelas harus secara eksplisit memanggil Dispose ketika Anda ingin segera merilis sumber daya.
Menerapkan IDisposable
Kelas yang mengimplementasikan antarmuka IDisposable harus menyertakan bagian kode ini:
Bidang untuk melacak apakah objek telah dibuang:
Protected disposed As Boolean = False
Kelebihan beban Dispose yang membebaskan sumber daya kelas. Metode ini harus dipanggil dengan metode Dispose dan
Finalize
kelas dasar:Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposed Then If disposing Then ' Insert code to free managed resources. End If ' Insert code to free unmanaged resources. End If Me.disposed = True End Sub
Implementasi Dispose yang hanya berisi kode berikut:
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub
Pengambil-alihan metode
Finalize
yang hanya berisi kode berikut:Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
Berasal dari Kelas yang Mengimplementasikan IDisposable
Kelas yang berasal dari kelas dasar yang mengimplementasikan antarmuka IDisposable tidak perlu mengambil alih salah satu metode dasar kecuali menggunakan sumber daya tambahan yang perlu dibuang. Dalam situasi itu, kelas turunan harus mengambil alih metode Dispose(disposing)
kelas dasar untuk membuang sumber daya kelas turunan. Pengambil-alihan ini harus memanggil metode Dispose(disposing)
kelas dasar.
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposed Then
If disposing Then
' Insert code to free managed resources.
End If
' Insert code to free unmanaged resources.
End If
MyBase.Dispose(disposing)
End Sub
Kelas turunan tidak boleh mengambil alih metode Dispose dan Finalize
kelas dasar. Ketika metode tersebut dipanggil dari instans kelas turunan, implementasi kelas dasar dari metode tersebut memanggil pengambil-alihan kelas turunan metode Dispose(disposing)
.
Pengumpulan Sampah dan Destruktor Finalisasi
.NET Framework menggunakan sistem pengumpulan sampah pelacakan referensi untuk merilis sumber daya yang tidak digunakan secara berkala. Visual Basic 6.0 dan versi yang lebih lama menggunakan sistem lain yang disebut penghitungan referensi untuk mengelola sumber daya. Meskipun kedua sistem melakukan fungsi yang sama secara otomatis, ada beberapa perbedaan penting.
CLR secara berkala menghancurkan objek ketika sistem menentukan bahwa objek tersebut tidak lagi diperlukan. Objek dirilis lebih cepat ketika sumber daya sistem berada dalam pasokan pendek, dan lebih jarang sebaliknya. Penundaan antara ketika objek kehilangan cakupan dan ketika CLR melepaskannya berarti bahwa, tidak seperti objek di Visual Basic 6.0 dan versi yang lebih lama, Anda tidak dapat menentukan dengan tepat kapan objek akan dihancurkan. Dalam situasi seperti itu, objek dikatakan memiliki masa pakai non-deterministik. Dalam kebanyakan kasus, masa pakai non-deterministik tidak mengubah cara Anda menulis aplikasi, selama Anda ingat bahwa destruktor Finalize
bisa tidak segera dijalankan ketika objek kehilangan cakupan.
Perbedaan lain antara sistem pengumpulan sampah melibatkan penggunaan Nothing
. Untuk memanfaatkan penghitungan referensi dalam Visual Basic 6.0 dan versi yang lebih lama, programmer terkadang menetapkan Nothing
ke variabel objek untuk merilis referensi yang dimiliki variabel tersebut. Jika variabel memegang referensi terakhir ke objek, sumber daya objek segera dirilis. Dalam versi Visual Basic yang lebih baru, meskipun mungkin ada kasus di mana prosedur ini masih berharga, menjalankannya tidak pernah menyebabkan objek yang dirujuk segera merilis sumber dayanya. Untuk segera merilis sumber daya, gunakan metode Dispose objek, jika tersedia. Satu-satunya waktu Anda harus mengatur variabel ke Nothing
adalah ketika masa pakainya lama relatif terhadap waktu yang diperlukan pengumpul sampah untuk mendeteksi objek yatim piatu.
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk