Spesifikasi nomor L (panjang) Java

96

Tampaknya ketika Anda mengetikkan angka di Java, kompilator secara otomatis membacanya sebagai integer, itulah sebabnya ketika Anda mengetikkan (long) 6000000000(bukan dalam range integer) akan mengeluh bahwa 6000000000itu bukan integer. Untuk memperbaiki ini, saya harus menjelaskan 6000000000L. Saya baru belajar tentang spesifikasi ini.

Apakah ada spesifikasi angka lain seperti short, byte, float, double? Sepertinya ini bagus untuk dimiliki karena (saya asumsikan) jika Anda dapat menentukan nomor yang Anda ketik pendek maka java tidak perlu membuangnya - itu asumsi, perbaiki saya jika saya salah . Saya biasanya akan mencari pertanyaan ini sendiri, tetapi saya tidak tahu apa nama spesifikasi nomor ini.

jbu
sumber

Jawaban:

174

Ada sufiks khusus untuk long(misalnya 39832L), float(misalnya 2.4f) dan double(misalnya -7.832d).

Jika tidak ada sufiks, dan merupakan tipe integral (misalnya 5623), maka diasumsikan sebagai int. Jika bukan merupakan tipe integral (misalnya 3.14159), diasumsikan sebagai a double.

Dalam semua kasus lain ( byte, short, char), Anda perlu pemain karena tidak ada akhiran tertentu.

Spesifikasi Java memungkinkan sufiks huruf besar dan kecil, tetapi versi huruf besar untuk longs lebih disukai, karena huruf besar Lkurang mudah dikacaukan dengan angka 1daripada huruf kecil l.

Lihat JLS bagian 3.10 untuk detail berdarah (lihat definisi IntegerTypeSuffix).

Simon Nickerson
sumber
9
Entri terlambat: menghapus potensi sumber ambiguitas selalu bagus, dan saya tidak setuju ... tapi saya yakin jika Anda bingung 1dengan ldan 0dengan O(dan seterusnya), prioritas Anda adalah mengatur font dengan benar (jika Anda bisa ), lalu khawatir tentang memastikan Anda tidak melewatkan tombol Shift.
davidcesarino
@SimonNickerson Saya punya pertanyaan tentang sufiks ... Jika saya mendeklarasikan variabel panjang atau ganda seperti: long _lo = 30;dan 30Lbukankah ini berarti variabel saya akan diubah menjadi float ? Atau dalam kasus _lo = _lo + 2.77yang _loakan dilemparkan ke pelampung meskipun telah dinyatakan lama
luigi7up
Tidak, pelampung tidak terlibat di sini. Dalam kasus pertama, 30adalah intyang secara otomatis dikonversi melalui konversi yang melebar menjadi long. Dalam kasus kedua, pernyataan Anda tidak sah. Anda harus secara eksplisit melemparkan sisi kanan ke long, misalnya_lo = (long) (_lo + 2.77)
Simon Nickerson
4
@DavidCesarino mengubah font memperbaiki ambiguitas untuk Anda - di editor tertentu tempat Anda mengaturnya dengan benar. Mengubah l ke L memperbaiki ambiguitas untuk semua orang yang mungkin pernah membaca kode Anda termasuk Anda sendiri ketika Anda membaca kode di Editor, IDE, melihat sumber di web yang berbeda (alat review, repositori, dll ..). Prioritas IMHO adalah jangan sampai melewatkan tombol Shift. Btw. font apa yang kamu rekomendasikan? Saya suka monospace dan defaultnya hampir di semua editor, CLIs dll yang pernah saya lihat dan dalam font ini ldan 1( 0dan Oresp.) Cukup mirip.
dingalapadum
1
@dingalapadum Seperti yang saya katakan, Anda benar. Menghapus sumber ambiguitas jelas merupakan hal yang benar untuk dilakukan. Saya baru saja mengatakan Anda harus mencoba untuk tidak menggunakan editor mana pun di mana Anda dapat dengan mudah salah mengira mereka. Dengan kata lain, saran lama coding defensif, tetapi tidak tergantung padanya. Tentang font, ini sangat pribadi, tapi saya selalu menggunakan Deja Vu Sans Mono kapanpun saya bisa karena 1) itu monospace; 2) tidak ada ambiguitas antar karakter; dan 3) Saya suka bentuknya, indah dan anggun, hampir seperti font sans-serif yang bagus dan dapat dibaca (font pemrograman bagus lainnya terasa IMHO terlalu "metalik").
davidcesarino
13

Saya harap Anda tidak keberatan sedikit bersinggungan, tetapi Anda mungkin tertarik untuk mengetahui bahwa selain F(untuk float), D(untuk ganda), dan L(untuk jangka waktu lama), sebuah proposal telah dibuat untuk menambahkan sufiks untuk bytedan short- Ydan Smasing - masing . Ini akan menghilangkan kebutuhan untuk mentransmisikan ke byte saat menggunakan sintaks literal untuk array byte (atau pendek). Mengutip contoh dari proposal:

MANFAAT UTAMA: Mengapa platform lebih baik jika proposal diadopsi?

kode kasar seperti

 byte[] stuff = { 0x00, 0x7F, (byte)0x80,  (byte)0xFF};

dapat dikodekan ulang sebagai

 byte[] ufum7 = { 0x00y, 0x7Fy, 0x80y, 0xFFy };

Joe Darcy mengawasi Project Coin untuk Java 7, dan blognya telah menjadi cara mudah untuk melacak proposal ini.

erickson
sumber
itu akan menyenangkan ... Saya selalu menemukan bahwa semua pemeran sangat menjengkelkan
jbu
Saya menganggap ini tidak membuatnya menjadi Java 7. Ada kabar apakah itu akan membuatnya menjadi pembaruan di masa mendatang atau Java 8?
hancurkan
@crush Saya mencoba memeriksanya beberapa bulan yang lalu, dan sejauh yang saya tahu, proposal tersebut telah ditinggalkan. Kami memang mendapatkan _ dalam literal numerik dan 0bawalan untuk literal biner. Teriakan.
erickson
Proposal ini mungkin diimplementasikan di kotlin daripada di java, karena oracle tidak ingin komunitas memberi tahu mereka cara bekerja ... kami berada di 2018 dan masih belum ada tentang proposal ini, sayangnya
JoelBonetR
11

Secara default, semua tipe data primitif integral (byte, short, int, long) akan diperlakukan sebagai tipe int oleh compiler java. Untuk byte dan short , selama nilai yang ditetapkan untuk mereka berada dalam jangkauannya, tidak ada masalah dan tidak diperlukan sufiks. Jika nilai yang ditetapkan ke byte dan short melebihi kisarannya, diperlukan pengecoran tipe eksplisit.

Ex:

byte b = 130; // CE: range is exceeding.

untuk mengatasi hal ini lakukan pengecoran tipe.

byte b = (byte)130; //valid, but chances of losing data is there.

Dalam kasus tipe data yang panjang, itu dapat menerima nilai integer tanpa kerumitan apapun. Misalkan kita menetapkan suka

Long l = 2147483647; //which is max value of int

dalam hal ini sufiks seperti L / l tidak diperlukan. Dengan nilai default 2147483647 dianggap oleh compiler java adalah tipe int. Pengecoran tipe internal dilakukan oleh compiler dan int secara otomatis dipromosikan ke tipe Long.

Long l = 2147483648; //CE: value is treated as int but out of range 

Di sini kita perlu meletakkan sufiks sebagai L untuk memperlakukan literal 2147483648 sebagai tipe panjang oleh compiler java.

jadi akhirnya

Long l = 2147483648L;// works fine.
Utpal Kumar
sumber
9

Ini adalah literal dan dijelaskan di bagian 3.10 dari spesifikasi bahasa Java.

McDowell
sumber
1

Sepertinya ini bagus untuk dimiliki karena (saya asumsikan) jika Anda dapat menentukan nomor yang Anda ketik pendek maka java tidak perlu memasukkannya

Karena penguraian literal terjadi pada waktu kompilasi, ini sama sekali tidak relevan dalam kaitannya dengan performa. Satu-satunya alasan memiliki shortdan bytesufiks akan menyenangkan adalah karena itu mengarah pada kode yang lebih kompak.

Michael Borgwardt
sumber
0

Untuk memahami mengapa perlu membedakan antara intdan longliteral, pertimbangkan:

long l = -1 >>> 1;

melawan

int a = -1;
long l = a >>> 1;

Sekarang seperti yang Anda harapkan, kedua fragmen kode memberikan nilai yang sama untuk variabel l. Tanpa bisa membedakan intdan longliteral, apa tafsirnya -1 >>> 1?

-1L >>> 1 // ?

atau

(int)-1 >>> 1 // ?

Jadi, meskipun angkanya berada dalam kisaran umum, kita perlu menentukan jenisnya. Jika default diubah dengan besaran literal, maka akan ada perubahan aneh dalam interpretasi ekspresi hanya dari mengubah digit.

Ini tidak terjadi untuk byte, shortdan charkarena mereka selalu dipromosikan sebelum melakukan operasi aritmatika dan bitwise. Bisa dibilang mereka harus berupa sufiks tipe integer untuk digunakan dalam, katakanlah, ekspresi inisialisasi array, tetapi tidak ada. floatmenggunakan sufiks fdan double d. Literal lain memiliki tipe yang tidak ambigu, dengan adanya tipe khusus untuk null.

Tom Hawtin - tackline
sumber
Saya akan sangat tertarik dengan apa yang Anda maksud di masa lalu. Dalam kedua kasus, saya mendapatkan 2147483647 dan saya tidak mengerti mengapa saya harus mengharapkan sesuatu yang lain.
Tanggal
@TheincredibleJan Anda tentu berharap Integer.MAX_VALUE, namun jika tidak ada cara untuk membedakan antara intdan longliteral, itu akan menjadi ambigu. / Saya tidak ingat pertanyaan ini, tetapi saya telah mengklarifikasi jawaban saya.
Tom Hawtin - tackline