Saya selalu bertanya-tanya mengapa Java tidak melakukan inferensi ketik mengingat bahasanya memang seperti itu, dan VM-nya sangat matang. Google's Go adalah contoh bahasa dengan inferensi jenis yang sangat baik dan mengurangi jumlah pengetikan yang harus dilakukan. Apakah ada alasan khusus di balik fitur ini yang tidak menjadi bagian dari Java?
44
Jawaban:
Secara teknis, Java memang memiliki tipe inferencing saat menggunakan obat generik. Dengan metode generik suka
Kompiler akan menganalisis dan memahami hal itu ketika Anda menulis
Sebuah String akan dikembalikan untuk panggilan pertama dan Integer untuk panggilan kedua berdasarkan apa yang dimasukkan sebagai argumen. Anda akan mendapatkan waktu kompilasi yang tepat sebagai hasilnya. Selain itu, di Java 7, seseorang bisa mendapatkan beberapa tipe tambahan yang menyimpulkan ketika instantiating generik seperti itu
Java cukup baik untuk mengisi kurung sudut kosong untuk kita. Sekarang mengapa Java tidak mendukung penaksiran tipe sebagai bagian dari penugasan variabel? Pada satu titik, ada RFE untuk tipe yang menyimpulkan dalam deklarasi variabel, tetapi ini ditutup sebagai "Tidak akan diperbaiki" karena
Kontributor yang menutup ini juga mencatat bahwa rasanya "tidak seperti java", yang saya setujui. Kata kerja Jawa bisa menjadi berkah sekaligus kutukan, tetapi itu membuat bahasa itu seperti apa adanya.
Tentu saja RFE tertentu itu bukan akhir dari percakapan itu. Selama Java 7, fitur ini sekali lagi dipertimbangkan , dengan beberapa implementasi pengujian dibuat, termasuk satu oleh James Gosling sendiri. Sekali lagi, fitur ini akhirnya ditembak jatuh.
Dengan dirilisnya Java 8, kami sekarang mendapatkan inferensi jenis sebagai bagian dari lambdas sebagai berikut:
Kompiler Java dapat melihat metode
Collections#sort(List<T>, Comparator<? super T>)
dan kemudian antarmukaComparator#compare(T o1, T o2)
dan menentukan itufirst
dansecond
harus denganString
demikian memungkinkan programmer untuk melupakan harus menyatakan kembali jenis dalam ekspresi lambda.sumber
First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns
- ya, jikaHashMap<String, Integer> map = foo.getMap()
kemudian saya setuju - dalam C # Saya biasanya tidak menggunakanvar
dalam kasus seperti itu, meskipun saya bisa. Tetapi argumen ini tidak menahan air jika ituHashMap<String, Integer> map = new HashMap<String, Integer>()
. Ini benar-benar redundansi dan saya melihat tidak ada manfaatnya karena harus menulis nama tipe dua kali. Dan bagaimana saya akan mendapat manfaat di sini dari pemeriksaan silang kompiler, saya tidak mengerti sama sekali.var
di Jawa.Humans benefit from the redundancy
adalah jawaban nyata untuk pertanyaan saat ini, karena setiap justifikasi yang saya baca tampaknya merupakan alasan yang tidak masuk akal, tidak berdasar, dan konyol dari para desainer Java: Baik C # dan C ++ memiliki fitur, desainer C # dan C ++ tidak kalah kompeten daripada Java, dan semua orang senang menggunakannya. Apa yang menyebabkan pengembang Java berbeda dari pengembang C # atau C ++? Ini adalah mengapa saya setuju dengan @KonradMorawski, "Ini adalah bagaimana hal-hal yang dilakukan di sini" tampaknya lagi menjadi alasan di balik layar nyata untuk itu.Yah, pertama-tama, tipe inferensi tidak ada hubungannya dengan kematangan runtime, apakah itu runtime adalah CPU berusia 30 tahun atau VM yang sangat baru bit-bitnya masih mengkilap. ini semua tentang kompiler.
Yang mengatakan, itu diperbolehkan untuk obat generik, alasan mengapa itu tidak diperbolehkan untuk jenis non-generik tampaknya karena filosofi - tidak ada yang mencegah desainer untuk menambahkannya.
Pembaruan: sepertinya java 10 mendukungnya —- http://openjdk.java.net/jeps/286
sumber
Sejauh yang saya tahu, ketika Java dirancang pada awal tahun sembilan puluhan jenis inferensi tidak begitu populer di antara bahasa-bahasa utama (tapi itu sudah konsep yang sangat terkenal, misalnya dalam ML). Jadi, saya bisa membayangkan bahwa inferensi jenis mungkin tidak didukung karena Java ditujukan untuk programmer yang berasal dari C ++, Pascal, atau bahasa utama lainnya yang tidak memilikinya (prinsip kejutan paling tidak).
Juga, salah satu prinsip desain Java adalah menulis hal-hal secara eksplisit untuk memastikan bahwa programmer dan kompiler memiliki pemahaman yang sama tentang kode: menggandakan informasi mengurangi kemungkinan kesalahan. Tentu saja, mungkin merupakan masalah selera apakah mengetik beberapa karakter sepadan dengan keamanan ekstra yang diberikannya, tetapi ini adalah filosofi desain yang diikuti untuk Jawa: menulis sesuatu secara eksplisit.
Saya tidak tahu apakah Java akan mendapatkan inferensi tipe di masa depan tetapi IMO yang akan menjadi revolusi besar untuk bahasa (seperti yang disebutkan Glenn Nelson, itu digambarkan sebagai "seperti-java-seperti") dan kemudian orang mungkin juga mempertimbangkan untuk menjatuhkan beri nama Java untuk nama baru.
Jika Anda ingin menggunakan bahasa JVM dengan tipe inferensi Anda dapat menggunakan Scala.
sumber
Saya dapat memikirkan beberapa kemungkinan alasan. Salah satunya adalah bahwa pengetikan secara eksplisit mendokumentasikan diri. Java umumnya menjadikan ini prioritas daripada keputusan. Alasan lain mungkin dalam kasus di mana jenisnya agak ambigu. Seperti ketika suatu jenis atau subtipe apa pun dapat memenuhi suatu rutinitas. Katakanlah Anda ingin menggunakan Daftar, tetapi seseorang datang dan menggunakan metode eksklusif untuk ArrayList. JIT akan menyimpulkan ArrayList dan melanjutkan bahkan jika Anda menginginkan kesalahan kompilasi.
sumber
Let's say you want to use a List, but someone comes along and uses a method exclusive to ArrayList. The JIT would infer an ArrayList and carry on even if you wanted a compilation error
- Saya tidak mengerti bagian ini. Ketik inferensi terjadi pada saat instatiating variabel, tidak memanggil metode di dalamnya. Bisakah Anda menunjukkan contoh dari apa yang Anda maksudkan?Ini bertentangan dengan rekomendasi mapan untuk mendeklarasikan variabel menggunakan antarmuka paling umum yang sesuai dengan kebutuhan Anda, dan menginisialisasi mereka dengan kelas implementasi yang tepat, seperti di
Secara efektif,
tidak lain adalah gula sintaksis untuk
Jika Anda menginginkannya, IDE Anda dapat memproduksinya dari
new ArrayList<String>()
ekspresi dengan "satu klik" (refactor / create variabel lokal), tetapi ingat bahwa itu bertentangan dengan rekomendasi "gunakan antarmuka".sumber