_ (garis bawah) adalah kata kunci yang dipesan

94

Saya baru saja mengganti sekspresi lambda berikut dengan _:

s -> Integer.parseInt(s)

Kompiler Eclipse mengatakan:

'_' tidak boleh digunakan sebagai pengenal, karena ini adalah kata kunci yang dipesan dari sumber level 1.8 di.

Saya belum menemukan penjelasan apa pun di JLS §3.9 Struktur Leksikal / Kata Kunci.

Aubin
sumber

Jawaban:

86

Tempat untuk mencarinya adalah JLS §15.27.1. Parameter Lambda

Ini adalah kesalahan waktu kompilasi jika parameter lambda memiliki nama _ (yaitu, satu karakter garis bawah).

Penggunaan nama variabel _ dalam konteks apa pun tidak disarankan. Versi bahasa pemrograman Java yang akan datang mungkin memesan nama ini sebagai kata kunci dan / atau memberinya semantik khusus.

Jadi, pesan Eclipse menyesatkan, terutama karena pesan yang sama digunakan untuk kedua kasus, saat error dibuat untuk parameter lambda atau saat peringatan dibuat untuk _pengenal lainnya .

Holger
sumber
24
Perhatikan bahwa mulai Java 9, _tidak akan diizinkan sebagai nama pengenal hukum dan tidak hanya sebagai nama parameter lambda. Ini sebenarnya telah diperbaiki dalam build 43: bugs.openjdk.java.net/browse/JDK-8061549
Jean-François Savard
3
@lscoughlin: Bukankah pernyataan “Versi bahasa pemrograman Java yang akan datang dapat memesan nama ini sebagai kata kunci dan / atau memberinya semantik khusus” cukup? Nah, ganti "may reserve" dengan "will use", dan Anda akan mendapatkan gambarannya. Mungkin referensi email ini membantu ...
Holger
6
Apa ini? Java melanggar kompatibilitas mundur?
Arturo Torres Sánchez
8
@Arturo Torres Sánchez: itu bukan hal baru. Ada saat-saat enumdan assertmerupakan pengenal resmi…
Holger
11
@Holger sebenarnya ada banyak bahasa yang menggunakan garis bawah sebagai placeholder nama (Scala, Clojure, F #, SML, Erlang, hanya untuk beberapa nama). Ini adalah pola mapan yang dimulai dari tahun 90-an atau 80-an, saya percaya, jadi tidak mematuhinya adalah aneh.
om-nom-nom
25

Ini adalah Fase 2 dari JEP 302 , yang akan menambahkan garis bawah sebagai karakter khusus untuk menunjukkan parameter yang tidak digunakan dalam ekspresi lambda.

Pengobatan garis bawah

Dalam banyak bahasa, adalah umum menggunakan garis bawah ( _) untuk menunjukkan parameter lambda tanpa nama (dan juga untuk metode dan parameter pengecualian):

BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);

Hal ini memungkinkan pemeriksaan statis yang lebih kuat atas argumen yang tidak digunakan, dan juga memungkinkan beberapa argumen ditandai sebagai tidak digunakan. Namun, karena garis bawah adalah pengenal yang valid pada Java 8, kompatibilitas mengharuskan kami untuk mengambil jalur yang lebih tidak langsung untuk mencapai tempat garis bawah dapat menjalankan peran ini di Java. Fase 1 melarang garis bawah sebagai nama parameter formal lambda di Java 8 (ini tidak memiliki konsekuensi kompatibilitas, karena lambda tidak ada sebelumnya) dan peringatan dikeluarkan untuk menggunakan garis bawah sebagai pengenal di tempat lain. Tahap 2 datang di Java 9, saat peringatan ini menjadi error. Kami sekarang bebas untuk menyelesaikan rehabilitasi garis bawah yang direncanakan untuk menunjukkan lambda, metode, atau parameter formal catch yang tidak digunakan.

Alexandre de Champeaux
sumber
2
Penggunaan ini dibahas oleh Brian Goetz dalam pembicaraan Devoxx tahun 2017-11 tentang Proyek Amber .
Basil Bourque
Oke, tapi apa alternatif untuk menunjukkan parameter yang tidak digunakan di J8? Apakah itu tidak mungkin sama sekali?
Manuel
1
Saat ini kami menggunakan $untuk tujuan ini.
aventurin
1
Saya menggunakan Java 14 sekarang, dan saya masih tidak dapat menggunakan garis bawah sebagai parameter lambda tanpa nama. Apa pun yang ingin dicapai JCP, tampaknya yang mereka capai sebaliknya.
Frans
1
@Frans Perhatikan bahwa JEP (sampai hari ini) hanya dalam tahap kandidat. Ini belum selesai. Untuk detail lebih lanjut tentang proses JEP
Alexandre de Champeaux