Il letterale xyz di tipo int è fuori intervallo


89

Al momento sto lavorando con i tipi di dati in Java e, se ho capito correttamente, il tipo longaccetta un valore compreso tra -9,223,372,036,854,775,808 e +9,223,372,036,854,775,807. Ora come puoi vedere sotto, ho creato una longvariabile chiamata testLong, anche se quando inserisco 9223372036854775807 come valore, ottengo un errore che dice:

Il letterale 9223372036854775807 del tipo int è fuori intervallo.

Non so perché si riferisca al longtipo di dati come file int.

Qualcuno ha qualche idea?

Codice:

char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;

A proposito: quale compilatore stai usando? Sia Eclipse che il compilatore Sun JDK forniscono messaggi di errore diversi (a mio parere migliori) per questo problema.
Joachim Sauer

Risposte:


195

Aggiungi una capitale Lalla fine:

long value = 9223372036854775807L;

Altrimenti, il compilatore proverà ad analizzare il letterale come un int, da cui il messaggio di errore


4
È nelle specifiche del linguaggio Java. Trova il testo completo qui
Lukas Eder

@Lukas, valore lungo = 00000077029062100L; mi dà lo stesso errore ed è inferiore a 19 cifre. qualsiasi idea sul perché sta lanciando "Il letterale 0000007702062100L di tipo lungo è fuori portata"
Santossh Kumhar

1
@SantosshKumhar: è un letterale ottale , che non può contenere cifre 8o 9. Rimuovi gli zeri iniziali.
Lukas Eder

49

Non so perché si riferisca al tipo di dati lungo come int

Non è. Dovresti imparare a fidarti dei messaggi del compilatore (specialmente quando provengono da compilatori sani e moderni e non da compilatori C / C ++ antichi). Anche se la lingua che parlano potrebbe essere difficile da decifrare a volte, di solito non ti mentono.

Guardiamolo di nuovo:

Il valore letterale di int 9223372036854775807 è fuori intervallo.

Nota che non menziona la tua variabile testLongo il tipo da longnessuna parte, quindi non riguarda l'inizializzazione. Il problema sembra verificarsi in un altro punto.

Ora esaminiamo alcune parti del messaggio:

  • intci dice che vuole trattare qualcosa come un intvalore (che non è quello che volevi!)
  • "fuori intervallo" è abbastanza chiaro: qualcosa non rientra nell'intervallo previsto (probabilmente quello di int)
  • "Il letterale": ora è interessante: cos'è un letterale?

Lascerò per un momento l'elenco accogliente per parlare di letterali: i letterali sono luoghi in cui hai un certo valore nel tuo codice. Ci sono Stringletterali, intletterali, classletterali e così via. Ogni volta che menzioni un valore in modo esplicito nel codice, è letterale.

Quindi non ti sta effettivamente tormentando per la dichiarazione della variabile, ma il numero stesso, il valore è ciò che ti tormenta.

Puoi facilmente verificarlo usando lo stesso letterale in un contesto in cui a longe an intsono ugualmente accettabili:

System.out.println(9223372036854775807);

PrintStream.printlnpuò richiedere unint o unlong (o praticamente qualsiasi altra cosa). Quindi quel codice dovrebbe andare bene, giusto?

No. Beh, forse dovrebbe essere, ma secondo le regole non va bene.

Il problema è che "alcune cifre" è definito come un valore intletterale e quindi deve essere compreso nell'intervallo definito da int.

Se vuoi scrivere un longletterale, devi renderlo esplicito aggiungendo L(o minuscolo l, ma ti consiglio caldamente di usare sempre la variante maiuscola, perché è molto più facile da leggere e più difficile da scambiare per a 1).

Notare che un problema simile si verifica con float(postfix F/ f) e double(postfix D/ d).

Nota a margine: ti renderai conto che non ci sono byteo shortletterali e puoi ancora assegnare valori (solitamente intletterali) a bytee shortvariabili: ciò è possibile grazie a regole speciali nel § 5.2 sulla Conversione di assegnazione : consentono l'assegnazione di espressioni costanti di un tipo più grande a byte, short, charo int se i valori sono fra i tipi gamma.


3
Da dove prendi il tempo ;-)
Lukas Eder

3
@Lukas: ogni tanto scrivo risposte del genere nella speranza di non dover scrivere 300 più brevi ;-) Inoltre: aiutare a interpretare il messaggio di errore (si spera) significa meno "cosa significa quel messaggio di errore" domande.
Joachim Sauer

la tua risposta è molto buona ... senza dubbio, ecco perché vota, ma per favore modificala e in alto (inizio della tua risposta), scrivi in ​​una riga la soluzione esatta del problema, e poi sotto la tua spiegazione. Perché molte persone cercano una soluzione rapida piuttosto che una spiegazione approfondita
Shirish Herwade

4
Sono liberi di guardare altre seconde risposte (quella con il voto più alto fornisce anche la soluzione rapida). Penso che istruire le persone su come analizzare e comprendere i messaggi di errore sia più utile a lungo termine che farlo solo per loro. "Dai un pesce a un uomo ..." e tutto il resto.
Joachim Sauer

Grazie per la nota a margine.
Venkatesh Goud

17

Prova a fare 9223372036854775807L. Alla Lfine dice a Java che 9223372036854775807è un file long.


0

Ho avuto questo problema in passato e l'ho risolto scrivendo il valore nella forma scientifica. per esempio:

double val = 9e300;

-2
long ak = 34778754226788444L/l;

Entrambi usano ma alla volta solo uno usa L maiuscola o l minuscola.

Perché usare L / l? Perché long è una parte del tipo di dati integrale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.