Saat ini saya sedang mengerjakan tugas untuk salah satu kelas saya, dan di dalamnya, saya harus memberikan contoh, menggunakan sintaks Java, pengikatan statis dan dinamis .
Saya memahami konsep dasar, bahwa pengikatan statis terjadi pada waktu kompilasi dan pengikatan dinamis terjadi pada waktu proses, tetapi saya tidak dapat mengetahui cara kerjanya secara spesifik.
Saya menemukan contoh online binding statis yang memberikan contoh ini:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
Dan ini akan mencetak "hewan sedang makan" karena panggilan untuk callEat
menggunakan pengikatan statis , tapi saya tidak yakin mengapa ini dianggap pengikatan statis.
Sejauh ini tidak ada sumber yang saya lihat berhasil menjelaskan hal ini dengan cara yang dapat saya ikuti.
java
dynamic-binding
static-binding
pengguna2309750
sumber
sumber
Jawaban:
Dari postingan blog yang dikunjungi Javare :
sumber
Menghubungkan panggilan metode ke badan metode disebut Binding. Seperti yang dikatakan Maulik, "Pengikatan statis menggunakan informasi Jenis (Kelas di Java) untuk pengikatan, sedangkan pengikatan dinamis menggunakan Objek untuk menyelesaikan pengikatan." Jadi kode ini:
Akan menghasilkan hasil: anjing sedang makan ... karena menggunakan referensi objek untuk menemukan metode yang akan digunakan. Jika kita mengubah kode di atas menjadi ini:
Ini akan menghasilkan: hewan sedang makan ... karena ini adalah metode statis, jadi menggunakan Jenis (dalam hal ini Hewan) untuk menyelesaikan metode statis mana yang harus dipanggil. Selain metode statis, metode privat dan final menggunakan pendekatan yang sama.
sumber
a
itu sebenarnya adalahDog
waktu kompilasi?Kompilator hanya mengetahui bahwa tipe "a" adalah
Animal
; ini terjadi pada waktu kompilasi, karena itu disebut pengikatan statis (Metode overloading). Tetapi jika itu adalah pengikatan dinamis maka itu akan memanggilDog
metode kelas. Berikut adalah contoh pengikatan dinamis.Hasil: Metode makan di dalam Anjing
sumber
Nah untuk memahami bagaimana mengikat statis dan dinamis sebenarnya bekerja? atau bagaimana mereka diidentifikasi oleh compiler dan JVM?
Mari kita ambil contoh di bawah ini di mana
Mammal
kelas induk yang memiliki metodespeak()
danHuman
kelas diperpanjangMammal
, menggantispeak()
metode dan kemudian membebani lagi denganspeak(String language)
.Ketika kita mengkompilasi kode di atas dan mencoba untuk melihat bytecode yang digunakan
javap -verbose OverridingInternalExample
, kita dapat melihat bahwa compiler menghasilkan tabel konstan di mana ia memberikan kode integer ke setiap panggilan metode dan kode byte untuk program yang telah saya ekstrak dan dimasukkan dalam program itu sendiri ( lihat komentar di bawah setiap panggilan metode)Dengan melihat kode di atas kita dapat melihat bahwa bytecode dari
humanMammal.speak()
,human.speak()
danhuman.speak("Hindi")
sama sekali berbeda (invokevirtual #4
,invokevirtual #7
,invokevirtual #9
) karena compiler mampu membedakan antara mereka berdasarkan daftar argumen dan referensi kelas. Karena semua ini diselesaikan pada waktu kompilasi secara statis, itulah sebabnya Overloading Metode dikenal sebagai Polimorfisme Statis atau Binding Statis. .Tetapi bytecode for
anyMammal.speak()
andhumanMammal.speak()
is same (invokevirtual #4
) karena menurut kompiler kedua metode dipanggilMammal
referensi.Jadi sekarang pertanyaannya muncul jika kedua pemanggilan metode memiliki bytecode yang sama lalu bagaimana JVM mengetahui metode mana yang harus dipanggil?
Jawabannya tersembunyi di bytecode itu sendiri dan itu adalah
invokevirtual
set instruksi. JVM menggunakaninvokevirtual
instruksi untuk memanggil Java yang setara dengan metode virtual C ++. Di C ++ jika kita ingin mengganti satu metode di kelas lain, kita perlu mendeklarasikannya sebagai virtual, Tetapi di Java, semua metode adalah virtual secara default karena kita dapat mengganti setiap metode di kelas anak (kecuali metode privat, final dan statis).Di Java, setiap variabel referensi memiliki dua pointer tersembunyi
Jadi semua referensi objek secara tidak langsung memiliki referensi ke tabel yang menampung semua referensi metode objek itu. Java telah meminjam konsep ini dari C ++ dan tabel ini dikenal sebagai tabel virtual (vtable).
Vtable adalah struktur seperti array yang menyimpan nama metode virtual dan referensinya pada indeks array. JVM hanya membuat satu vtabel per kelas saat memuat kelas ke dalam memori.
Jadi setiap kali JVM menemukan
invokevirtual
set instruksi, ia memeriksa vtable kelas itu untuk referensi metode dan memanggil metode tertentu yang dalam kasus kami adalah metode dari objek bukan referensi.Karena semua ini diselesaikan hanya pada saat runtime dan pada saat runtime JVM mengetahui metode mana yang akan dipanggil, itulah mengapa Metode Overriding dikenal sebagai Dynamic Polymorphism atau hanya Polymorphism atau Dynamic Binding .
Anda dapat membacanya lebih detail di artikel saya Bagaimana JVM Menangani Metode Overloading dan Overriding Secara Internal .
sumber
Ada tiga perbedaan utama antara pengikatan statis dan dinamis saat mendesain kompiler dan bagaimana variabel dan prosedur ditransfer ke lingkungan runtime . Perbedaan tersebut adalah sebagai berikut:
Pengikatan Statis : Dalam pengikatan statis, tiga masalah berikut dibahas:
Definisi prosedur
Deklarasi nama (variabel, dll.)
Lingkup deklarasi
Dynamic Binding : Tiga masalah yang muncul dalam dynamic binding adalah sebagai berikut:
Aktivasi prosedur
Mengikat nama
Seumur hidup yang mengikat
sumber
Dengan metode statis di kelas induk dan anak: Static Binding
Pengikatan Dinamis:
sumber
Semua jawaban di sini benar tetapi saya ingin menambahkan sesuatu yang hilang. ketika Anda menimpa metode statis, sepertinya kita menimpanya tetapi sebenarnya itu bukan penimpaan metode. Sebaliknya itu disebut metode persembunyian. Metode statis tidak dapat diganti di Java.
Lihat contoh di bawah ini:
Dalam pengikatan dinamis, metode disebut tergantung pada jenis referensi dan bukan jenis objek yang dipegang oleh variabel referensi. Di sini pengikatan statis terjadi karena penyembunyian metode bukanlah polimorfisme dinamis. Jika Anda menghapus kata kunci statis di depan eat () dan menjadikannya sebagai metode non-statis, maka itu akan menunjukkan kepada Anda polimorfisme dinamis dan bukan penyembunyian metode.
saya menemukan tautan di bawah ini untuk mendukung jawaban saya: https://youtu.be/tNgZpn7AeP0
sumber
Dalam kasus jenis pengikatan statis objek ditentukan pada waktu kompilasi sedangkan dalam jenis pengikatan dinamis objek ditentukan pada waktu proses.
sumber
Karena kompilator mengetahui pengikatan pada waktu kompilasi. Jika Anda memanggil sebuah metode pada sebuah antarmuka, misalnya, maka compiler tidak dapat mengetahui dan pengikatan diselesaikan pada saat runtime karena objek sebenarnya yang memiliki metode yang dipanggil dapat menjadi salah satu dari beberapa. Oleh karena itu, itu adalah runtime atau dynamic binding.
Permintaan Anda terikat pada kelas Animal pada waktu kompilasi karena Anda telah menentukan tipenya. Jika Anda meneruskan variabel itu ke metode lain di tempat lain, tidak ada yang akan tahu (selain Anda karena Anda menulisnya) kelas sebenarnya apa itu. Satu-satunya petunjuk adalah jenis Hewan yang dideklarasikan.
sumber