Baru-baru ini saya membaca kode sumber Spring Framework. Sesuatu yang tidak saya mengerti diletakkan di sini:
public Member getMember() {
// NOTE: no ternary expression to retain JDK <8 compatibility even when using
// the JDK 8 compiler (potentially selecting java.lang.reflect.Executable
// as common type, with that new base class not available on older JDKs)
if (this.method != null) {
return this.method;
}
else {
return this.constructor;
}
}
Metode ini adalah anggota kelas org.springframework.core.MethodParameter
. Kode mudah dimengerti sementara komentarnya sulit.
CATATAN: tidak ada ekspresi terner untuk mempertahankan kompatibilitas JDK <8 bahkan ketika menggunakan kompiler JDK 8 (berpotensi memilih
java.lang.reflect.Executable
sebagai tipe umum, dengan kelas dasar baru itu tidak tersedia pada JDK lama)
Apa perbedaan antara menggunakan ekspresi terner dan menggunakan if...else...
konstruk dalam konteks ini?
sumber
Ini diperkenalkan di commit yang cukup lama pada tanggal 3 Mei 2013, hampir setahun sebelum rilis resmi JDK-8. Kompiler sedang dalam pengembangan berat pada waktu itu, sehingga masalah kompatibilitas dapat terjadi. Saya kira, tim Spring baru saja menguji build JDK-8 dan mencoba memperbaiki masalah, meskipun sebenarnya itu adalah masalah compiler. Dengan rilis resmi JDK-8 ini menjadi tidak relevan. Sekarang operator terner dalam kode ini berfungsi dengan baik seperti yang diharapkan (tidak ada referensi ke
Executable
kelas dalam file .class yang dikompilasi).Saat ini hal serupa muncul di JDK-9: beberapa kode yang dapat dikompilasi dengan baik di JDK-8 gagal dengan JDK-9 javac. Saya kira, sebagian besar masalah seperti itu akan diperbaiki hingga rilis.
sumber
Executable
, melanggar beberapa aspek spesifikasi? Atau apakah hanya karena Oracle menyadari bahwa mereka dapat mengubah perilaku ini dengan cara yang tetap sesuai dengan spesifikasi dan tanpa merusak kompatibilitas ke belakang?Executable
mengetik di antaranya. Di Java-8, konsep inferensi tipe ekspresi berubah secara drastis dan bagian ini telah sepenuhnya ditulis ulang, sehingga tidak mengherankan jika implementasi awal memiliki bug.Perbedaan utama adalah bahwa
if
else
blok adalah pernyataan sedangkan terner (lebih sering dikenal sebagai operator bersyarat di Jawa) adalah ekspresi .Sebuah pernyataan dapat melakukan hal-hal seperti
return
ke pemanggil pada beberapa jalur kontrol. Sebuah ekspresi dapat digunakan dalam tugas:int n = condition ? 3 : 2;
Jadi dua ekspresi di terner setelah kondisi perlu dipaksakan ke tipe yang sama. Hal ini dapat menyebabkan beberapa efek aneh di Java terutama dengan auto-boxing dan transmisi referensi otomatis - inilah yang dirujuk oleh komentar dalam kode yang Anda posting. Pemaksaan ekspresi dalam kasus Anda akan menjadi
java.lang.reflect.Executable
tipe (karena itu adalah tipe yang paling terspesialisasi ) dan itu tidak ada di versi Java yang lebih lama.Secara gaya Anda harus menggunakan
if
else
blok jika kodenya seperti pernyataan, dan terner jika seperti ekspresi.Tentu saja, Anda dapat membuat
if
else
blok berperilaku seperti ekspresi jika Anda menggunakan fungsi lambda.sumber
Jenis nilai yang dikembalikan dalam ekspresi terner dipengaruhi oleh kelas induk, yang diubah seperti yang dijelaskan di Java 8.
Sulit untuk melihat mengapa pemeran tidak bisa ditulis.
sumber