Awal pekan ini, kami melaporkan rilis versi 1.0.0 dari proyek JSpecify. Rilis ini berfokus pada penyediaan anotasi penggunaan tipe untuk menunjukkan kapan tipe statis tidak valid.
Terkait dengan topik ini, Draf JEP 8303099 Baru-baru ini diterbitkan. JEP ini membahas tipe nullable dan nullable, dan bertujuan untuk memperkenalkan Menandai adalah opsional Ke bahasa Jawa.
Tujuannya adalah untuk menambahkan tag – bukan hanya anotasi – ke penggunaan suatu tipe untuk menentukan apakah kumpulan nilai yang diizinkan untuk penggunaan tersebut mencakup null
Pertama. Penting untuk diingat bahwa proposal ini masih dalam tahap awal pengembangan (misalnya, belum memiliki nomor JEP resmi), sehingga sintaksisnya mungkin berubah. Karena itu, saat ini, tag mirip Kotlin digunakan untuk mengetik Foo
Ada tiga kemungkinan bagaimana tipe dapat digunakan:
Foo!
Dia adalah Terikat oleh ketiadaan – Nilai yang dapat diterima untuk penggunaan jenis ini tidak termasuknull
Foo?
Dia adalah Ruang kosong – Nilai yang dapat diterima untuk penggunaan tipe ini secara eksplisit disertakannull
Foo
Tidak disebutkan apakah atau tidaknull
dapat diterima
Gunakan telanjang Foo
Standarnya tetap sama, dimana arti kode yang sudah ada tidak boleh berubah ketika dikompilasi.
Saat ini, proposal memerlukan setiap penggunaan tipe untuk dianotasi, yaitu tidak ada cara untuk menandai seluruh kelas atau modul sebagai dibatasi menjadi null (seperti yang mungkin dilakukan di JSpecify), meskipun kemampuan ini dapat ditambahkan nanti.
Fitur baru ini memperkenalkan konversi yang tidak bernilai (mirip dengan konversi ekspansi dan unboxing). Misalnya, salah satu jenis pemetaan berikut diperbolehkan:
Foo!
keFoo?
Foo!
keFoo
Foo?
keFoo
Foo
keFoo?
Karena mewakili pelonggaran batasan – misalnya, nilai apa pun yang dibatasi oleh null dapat direpresentasikan dalam penggunaan tipe yang dapat dibatalkan.
Ada juga transformasi penyempitan nol, seperti:
Hal ini dapat menyebabkan kesalahan runtime, misalnya saat mencoba memuat null
Dari a Foo?
ke Foo!
. Strategi umum di sini adalah untuk memperlakukan kasus-kasus ini sebagai peringatan waktu kompilasi (tetapi bukan kesalahan) dan menyertakan pemeriksaan runtime yang menimbulkan NullPointerException
Jika batas nol dilanggar.
Perhatikan bahwa ini sebagian besar merupakan kasus yang mudah, dan kasus yang lebih kompleks juga mungkin dilakukan. Misalnya, ketika berhadapan dengan objek generik, kompiler mungkin menghadapi situasi seperti argumen tipe yang nilai nullnya tidak sesuai dengan batasan yang dinyatakan.
Memperkenalkan flag null memberikan keamanan lebih pada waktu kompilasi, dan memungkinkan adopsi flag secara bertahap – pertama dengan menentukan bahwa tidak ada tipe, kemudian berupaya menghilangkan peringatan pada waktu kompilasi.
InfoQ berbicara dengan Kevin Borillion (pendiri tim Perpustakaan Inti di Google dan sekarang anggota tim bahasa Java di Oracle) – untuk mendapatkan detail lebih lanjut tentang proyek ini.
InfoQ: Bisakah Anda menjelaskan latar belakang Anda mengenai upaya zero-sum di Java?
Boriliun: Saya ikut mendirikan grup JSpecify, dan merupakan salah satu “desainer” utama (didefinisikan sebagai “orang yang menanggung beban dalam mendorong keputusan desain yang rumit hingga mencapai konsensus dengan satu atau lain cara”). Saya sekarang telah pindah ke Oracle tetapi saya masih terlibat dalam banyak hal yang sama.
InfoQ: Bagaimana JEP ini mengganggu kerja JSpecify?
Boriliun: Pada akhirnya, kita akan memiliki Java yang mendukung tag null. JSpecify telah bekerja keras untuk menunjukkan dengan tepat makna semantik dari anotasi tersebut. Ini berarti bahwa setiap proyek garis waktu pemutakhiran yang memilih untuk mengadopsinya akan berada dalam posisi yang sangat baik untuk berpindah dari JSpecify ke zero-tags pada tingkat bahasa – pada kenyataannya, transisi harus sangat dapat diotomatisasi.
InfoQ: Tampaknya ada beberapa kesamaan antara rancangan JEP 8303099 dan cara publik ditambahkan, dahulu kala di Java 5. Apakah ini benar? Ini sebagian besar merupakan mekanisme waktu kompilasi, yang sebagian besar dibersihkan pada tingkat bytecode, bukan?
Boriliun: Ya, ada beberapa kesamaan yang berguna di sini. Kami memandang pemusnahan spesies dan momok “polusi besar-besaran” sebagai kompromi yang disayangkan, namun hal itulah yang membuat fitur ini begitu dapat diadopsi. Itu sebabnya Anda tidak perlu melihat tipe mentah lagi (saya harap!). Dalam kasus kami, nol polusi akan menjadi bagian dari realitas kita untuk waktu yang lama, tapi tidak apa-apa! Saat ini, semuanya bebas polusi.
Dan ya, seperti informasi tipe umum, komentar Anda tentang tidak memiliki nilai tersedia saat runtime melalui refleksi, tetapi komentar tersebut tidak terlibat dalam pemeriksaan tipe saat runtime. Saya tertarik untuk melihat apakah ada orang yang membuat alat bytecode yang memasukkan pemeriksaan nol berdasarkan masukan kami; Saya dapat melihat alasan mengapa hal ini mungkin sangat membantu dan alasan mengapa hal tersebut mungkin tidak bermanfaat; Kita harus melihatnya.
InfoQ: Kendala nilai nol juga merupakan topik penting untuk proyek Valhalla, bukan? Apa yang dapat Anda sampaikan mengenai interaksi antara rancangan JEP ini dan upaya yang sedang berlangsung di bidang ini?
Boriliun: Ini sebenarnya pertanyaan yang sama; Valhalla hanya akan didasarkan pada draft JEP yang saya sebutkan. Mengetahui apa yang tidak boleh kosong akan membantu VM mengatasi kebingungan ini.
InfoQ: Dalam jangka menengah hingga panjang, JSpecify harus mampu menyediakan cara untuk mendukung nullability tingkat bahasa di Java. Hal ini serupa dengan cara penggunaannya untuk berinteraksi dengan dukungan nullability Kotlin. Bagaimana Anda merekomendasikan pembaca untuk mengadopsi JSpecify hari ini?
Boriliun: File jar JSpecify hanya versi 1.0.0. Spesifikasinya, yang menentukan arti penjelasan yang sangat tepat, masih dapat mengalami perubahan (kecil dan tidak kentara). Jadi jika Anda berusaha keras menjelaskan basis kode Anda hari ini, kode Anda tidak akan tiba-tiba berhenti dikompilasi dengan benar, tetapi setelah beberapa revisi kecil pada spesifikasi, Anda mungkin ingin menghapus beberapa simbol `@Nullable` di sini atau tambahkan beberapa lagi di sana.
Jika menerapkan analisis nol ke dalam rantai alat Anda saat ini memakan waktu terlalu lama karena semua peringatan di luar sana yang harus Anda bersihkan, sebenarnya sangat masuk akal untuk menambahkan `@SuppressWarnings` apa pun cakupan yang Anda perlukan! Agak tidak sedap dipandang, tapi itu adalah sesuatu yang bisa Anda bersihkan secara bertahap seiring berjalannya waktu. Walaupun lama, intinya *kode baru* akan mulai diperiksa hari ini, dan itulah kode yang paling penting untuk diperiksa.
InfoQ: Terima kasih!
“Pop culture ninja. Social media enthusiast. Typical problem solver. Coffee practitioner. Fall in love. Travel enthusiast.”