JVM mendukung begitu banyak bahasa selain Java seperti Groovy,Clojure,Scala
dll yang bahasa fungsional seperti Java (Saya mengacu pada Java sebelum Versi 8 di mana Lambda's
tidak didukung) yang tidak mendukung fungsional capabilities.On tingkat tinggi yang membuat JVM sangat serbaguna yang dapat mendukung baik Bahasa Berorientasi Objek maupun Fungsional?
18
Jawaban:
Dibandingkan dengan VM lain, JVM sebenarnya tidak terlalu serbaguna . Ini secara langsung mendukung OO yang diketik secara statis. Untuk yang lainnya, Anda harus melihat bagian apa yang dapat Anda gunakan, dan bagaimana Anda bisa membangun semua yang dibutuhkan bahasa Anda di atas bagian-bagian itu.
Sebagai contoh, sampai Java 7 memperkenalkan
invokedynamic
bytecode, sangat sulit untuk mengimplementasikan bahasa OO yang diketik secara dinamis di JVM - Anda harus menggunakan solusi kompleks yang buruk untuk kinerja dan menghasilkan jejak tumpukan yang membengkak.Namun, banyak bahasa dinamis (Groovy, Jython, JRuby, antara lain) diimplementasikan pada JVM sebelumnya.
Bukan karena JVM sangat fleksibel, tetapi karena sangat luas, dan karena ia memiliki implementasi yang sangat matang, didukung dengan baik, dan berkinerja tinggi.
Dan, mungkin bahkan lebih penting, karena ada sejumlah besar kode Java di luar sana melakukan cukup banyak hal, dan jika bahasa Anda berjalan pada JVM, Anda dapat dengan mudah menawarkan fasilitas untuk berintegrasi dengan kode itu. Pada dasarnya, menjalankan bahasa Anda di JVM adalah versi abad ke-21 yang menawarkan interoperabilitas dengan C.
sumber
JVM ditulis pada dasarnya bertindak seperti CPU, ada satu set instruksi, semacam perakitan, yang dijalankan oleh VM disebut bytecodes. Jika Anda dapat menulis kompiler yang menghasilkan set bytecode yang valid, maka JVM dapat menjalankannya.
Wikipedia memiliki daftar bytecodes:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
serta penjelasan tentang bagaimana JVM memuat kode byte:
http://en.wikipedia.org/wiki/Java_virtual_machine
Dengan menggunakan bytecodes style invoke, bahasa fungsional dapat mengeksekusi kode, apa pun sumbernya. Juga, dengan penambahan invokevirtual, implementasi bahasa seperti jruby telah memberikan beberapa fleksibilitas dengan bagaimana mereka berjalan.
sumber
Saya akan menambahkan bahwa JVM mendukung Memory Model ( JMM ) yang didefinisikan dengan baik dan cukup baik yang berarti dukungan yang baik untuk perilaku threading yang konsisten (meskipun tingkat rendah). Ini juga memiliki kompiler Just In Time yang kuat (tidak lebih berguna untuk bahasa yang dinamis berkat MethodHandles dan invokedynamic).
Terakhir namun tidak kalah pentingnya adalah sub-sistem Pengumpulan Sampah JVM yang (dengan penyetelan yang tepat) mengelola memori untuk Anda terlepas dari bahasa di atasnya.
sumber
someField = new int[]{42};
satu-satunya cara untuk memastikan bahwa setiap utas yang melihat array baru akan melihat nilainya 42 adalah untuk membuat lapanganfinal
atauvolatile
. Jika bidang dihasilkan dengan malas tetapi sering diakses, membuatnyafinal
tidak berfungsi, dan membuatnyavolatile
dapat memberikan hukuman sinkronisasi yang tidak perlu setiap kali diakses. Bahkan model .NET yang paling longgar ...Elemen kunci dalam hal ini adalah pemisahan kompilasi dari fase eksekusi. Dengan ini dimungkinkan untuk menulis kompiler lain yang mengkompilasi bahasa lain ke bytecode.
Bytecode bertindak serupa dengan kode mesin CPU - Anda memiliki semua operasi kecil yang diperlukan untuk menjalankan program - Anda bisa mendapatkan variabel, melakukan perhitungan matematika, melakukan operasi bersyarat dll.
Java juga tidak spesial. Di Jawa keberadaan beberapa bahasa bahkan bukan tujuan desain, tidak seperti VM lainnya. Untuk Microsoft .Net CIL , kemampuan untuk menjalankan banyak bahasa (C #, VB.Net, ...) adalah elemen desain utama, juga ParrotVM dari proyek Perl6 yang bertujuan untuk menjadi VM generik.
Untuk bersenang-senang, saya pernah membuat bukti bahwa bahkan Zend Engine PHP akan mengizinkannya.
Dan terus terang ini bukan sesuatu yang baru - bahkan pada perangkat keras nyata Anda dapat menjalankan beberapa bahasa - yaitu C atau Fortran.
Perbedaan pemisahan ini dari kompilasi dan eksekusi adalah penerjemah clssic, seperti beberapa bentuk Dasar, skrip shell, dll. Mereka sering bekerja dengan cara yang mengeksekusi kode kurang lebih dalam garis demi garis tanpa membawanya dalam bentuk langsung diantara.
sumber
JVM adalah mesin virtual pertama yang saya ketahui menggabungkan pengumpulan sampah, kinerja, dan model kotak pasir yang bisa diterapkan. Munculnya banyak bahasa untuk mendukung JVM mungkin bukan karena "fleksibilitas" -nya, melainkan fakta bahwa bahasa Jawa tidak memiliki beberapa fitur signifikan yang diinginkan orang dalam bahasa pemrograman. Sebagai contoh, sementara sebagian besar bahasa mesin hanya memiliki sekitar setengah lusin tipe data (mis. Byte, halfword, word, double-word, float presisi tunggal, dan float presisi ganda), sebagian besar bahasa pemrograman memungkinkan kode untuk menggunakan kode jumlah sewenang-wenang dari tipe data yang ditentukan pengguna. JVM mengenali beberapa tipe primitif yang mirip dengan yang ada pada mesin biasa, ditambah satu tipe lagi: Referensi Obyek Promiscuous. Bahasa Jawa juga mengakui primitif itu, dan Referensi Obyek Promiscuous. Sementara variabel mungkin dibatasi untuk tidak memegang referensi ke apa pun yang bukan kelas tertentu, bahasa tidak membuat perbedaan antara salah satu dari jenis bidang bidang berikut
List<String>
yang mungkin dipegang olehMyThing
kelas instanMyClass
:Referensi ke sesuatu kode tahu menjadi implementasi abadi
List<String>
Referensi ke instance dari tipe daftar yang bisa berubah yang tidak akan pernah terpapar pada apa pun yang mungkin bermutasi.
Referensi ke daftar yang dapat berubah yang, kecuali selama pelaksanaan
MyThings
metode, tidak ada referensi lain yang mungkin ada di mana pun di alam semesta.Referensi ke daftar yang dapat diubah yang dimiliki oleh beberapa objek lain , yang ingin
MyThing
digunakan oleh objek lain dengan cara tertentu.Referensi ke daftar yang bisa berubah yang
MyThing
dimiliki, tetapi yang juga terkena beberapa objek lain sehingga mereka dapat melakukan sesuatu dengannya.Meskipun semua bidang itu bisa memiliki tipe
List<String>
, mereka memiliki hal-hal yang sangat berbeda. Bahasa ekspresif memungkinkan perbedaan di antara makna-makna itu, tetapi Java tidak. Karena suatu bahasa dapat melampirkan makna pada hal-hal seperti itu (setidaknya di luar konteks generik) dan dijalankan pada JVM, itu menyisakan banyak ruang bagi bahasa-bahasa yang ditargetkan JVM untuk mengekspresikan konsep-konsep yang tidak bisa dilakukan Java.sumber