Xyz literal dari tipe int berada di luar jangkauan

90

Saya sedang mengerjakan tipe data saat ini di Java, dan jika saya telah memahami dengan benar tipe tersebut longmenerima nilai antara kisaran -9.223.372.036.854.775.808 hingga +9.223.372.036.854.775.807. Sekarang seperti yang Anda lihat di bawah, saya telah membuat longvariabel bernama testLong, meskipun ketika saya memasukkan 9223372036854775807 sebagai nilainya, saya mendapatkan kesalahan yang menyatakan:

Literal 9223372036854775807 dari tipe int berada di luar jangkauan.

Saya tidak tahu mengapa ini mengacu pada longtipe data sebagai file int.

Ada yang punya ide?

Kode:

char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Mathew Donnan
sumber
Omong-omong: kompiler apa yang Anda gunakan? Baik Eclipse dan kompiler JDK Sun memberikan pesan kesalahan yang berbeda (menurut saya lebih baik) untuk masalah ini.
Joachim Sauer

Jawaban:

196

Tambahkan modal Lsampai akhir:

long value = 9223372036854775807L;

Jika tidak, kompilator akan mencoba mengurai literal sebagai sebuah int, karenanya muncul pesan kesalahan

Lukas Eder
sumber
4
Ini ada dalam spesifikasi bahasa Java. Temukan teks lengkapnya di sini
Lukas Eder
@Lukas, nilai panjang = 00000077029062100L; memberi saya kesalahan yang sama, dan kurang dari 19 digit. Ada Ide mengapa itu membuang "The 0000007702062100L literal jenis panjang berada di luar jangkauan"
Santossh Kumhar
1
@SantosshKumhar: Itu literal oktal , yang tidak boleh berisi angka 8atau 9. Hapus angka nol di depan.
Lukas Eder
51

Saya tidak tahu mengapa ini mengacu pada tipe data panjang sebagai int

Bukan itu. Anda harus belajar memercayai pesan kompilator (terutama jika pesan tersebut berasal dari kompiler modern yang waras dan bukan dari kompiler C / C ++ kuno). Meskipun bahasa yang mereka gunakan terkadang sulit diartikan, mereka biasanya tidak berbohong kepada Anda.

Mari kita lihat lagi:

Literal int 9223372036854775807 berada di luar jangkauan.

Perhatikan, itu tidak menyebutkan variabel Anda testLongatau jenisnya di longmana pun, jadi ini bukan tentang inisialisasi. Masalahnya tampaknya terjadi di beberapa titik lain.

Sekarang mari kita selidiki beberapa bagian dari pesan tersebut:

  • intmemberi tahu kami bahwa dia ingin memperlakukan sesuatu sebagai intnilai (yang bukan yang Anda inginkan!)
  • "di luar jangkauan" cukup jelas: ada sesuatu yang tidak dalam kisaran yang diharapkan (mungkin dari int)
  • "The literal": sekarang itu menarik: apa itu literal?

Saya akan meninggalkan daftar nyaman untuk membicarakan literal sejenak: literal adalah tempat di mana Anda memiliki nilai dalam kode Anda. Ada Stringliteral, intliteral, classliteral dan sebagainya. Setiap kali Anda menyebutkan nilai secara eksplisit dalam kode Anda, itu literal.

Jadi sebenarnya ini tidak mengganggu Anda tentang deklarasi variabel, tetapi nomor itu sendiri, nilainya adalah apa yang mengganggu Anda.

Anda dapat dengan mudah memverifikasi ini dengan menggunakan literal yang sama dalam konteks di mana a longdan an intsama-sama dapat diterima:

System.out.println(9223372036854775807);

PrintStream.printlndapat mengambil salah satuint atau along (atau yang lainnya). Jadi kode itu seharusnya baik-baik saja, bukan?

No Yah, mungkin itu harus menjadi, tetapi menurut aturan itu adalah tidak baik.

Masalahnya adalah bahwa "beberapa digit" didefinisikan sebagai intliteral dan oleh karena itu harus berada dalam kisaran yang ditentukan oleh int.

Jika Anda ingin menulis longliteral, maka Anda harus membuatnya eksplisit dengan menambahkan L(atau huruf kecil l, tapi saya sangat menyarankan Anda selalu menggunakan varian huruf besar, karena jauh lebih mudah dibaca dan lebih sulit untuk salah untuk a 1).

Perhatikan bahwa masalah serupa terjadi dengan float(postfix F/ f) dan double(postfix D/ d).

Catatan samping: Anda akan menyadari bahwa tidak ada byteatau shortliteral dan Anda masih dapat menetapkan nilai (biasanya intliteral) ke variabel bytedan short: hal itu dimungkinkan karena aturan khusus di § 5.2 tentang Assignment Converson : mereka mengizinkan penetapan ekspresi konstan dari tipe yang lebih besar untuk byte, short, charatau int jika nilai-nilai dalam jenis berkisar.

Joachim Sauer
sumber
3
Di mana Anda meluangkan waktu dari ;-)
Lukas Eder
3
@ Lukas: Saya kadang-kadang menulis jawaban seperti itu dengan harapan saya tidak perlu menulis 300 jawaban yang lebih pendek untuk itu ;-) Juga: membantu menafsirkan pesan kesalahan (mudah-mudahan) berarti lebih sedikit pertanyaan "apa arti pesan kesalahan itu".
Joachim Sauer
jawaban Anda sangat bagus ... tidak diragukan lagi, itu sebabnya pilih-pilih, tetapi harap edit dan di atas (awal jawaban Anda), cukup tulis dalam 1 baris solusi yang tepat untuk masalah tersebut, lalu di bawah penjelasan Anda. Karena banyak orang mencari solusi cepat daripada penjelasan yang dalam
Shirish Herwade
4
Mereka bebas melihat jawaban kedua lainnya (jawaban tertinggi bahkan memberikan solusi cepat). Menurut saya, mendidik orang tentang cara mengurai dan memahami pesan kesalahan lebih berguna dalam jangka panjang daripada hanya melakukannya untuk mereka. "Beri seseorang ikan ..." dan semua itu.
Joachim Sauer
Terima kasih untuk catatan sampingnya.
Venkatesh Goud
19

Coba lakukan 9223372036854775807L. Di Lbagian akhir memberitahu Java bahwa 9223372036854775807adalah a long.

jontro
sumber
0

Saya memiliki masalah ini di masa lalu dan saya memperbaikinya dengan menuliskan nilai dalam bentuk ilmiah. sebagai contoh:

double val = 9e300;

sumber
-2
long ak = 34778754226788444L/l;

Keduanya menggunakan tetapi pada satu waktu hanya satu menggunakan huruf besar L atau huruf kecil l.

Mengapa menggunakan L / l? Karena panjang adalah bagian dari tipe data integral.

Akkushwaha
sumber