Das Literal xyz vom Typ int liegt außerhalb des Bereichs

89

Ich arbeite zurzeit mit Datentypen in Java, und wenn ich das richtig verstanden habe, longakzeptiert der Typ einen Wert zwischen den Bereichen -9.223.372.036.854.775.808 und +9.223.372.036.854.775.807. Wie Sie unten sehen können, habe ich eine longVariable mit dem Namen erstellt testLong. Wenn ich jedoch 9223372036854775807 als Wert einfüge, wird folgende Fehlermeldung angezeigt:

Das Literal 9223372036854775807 vom Typ int liegt außerhalb des Bereichs.

Ich weiß nicht, warum es sich um den longDatentyp als handelt int.

Hat jemand irgendwelche Ideen?

Code:

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
quelle
Übrigens: Welchen Compiler verwenden Sie? Sowohl Eclipse als auch der Sun JDK-Compiler geben unterschiedliche (meiner Meinung nach bessere) Fehlermeldungen für dieses Problem aus.
Joachim Sauer

Antworten:

195

Fügen Sie Lam Ende ein Kapital hinzu :

long value = 9223372036854775807L;

Andernfalls versucht der Compiler, das Literal als zu analysieren int, daher die Fehlermeldung

Lukas Eder
quelle
4
Es ist in den Java-Sprachspezifikationen. Den vollständigen Text finden Sie hier
Lukas Eder
@ Lukas, langer Wert = 00000077029062100L; gibt mir den gleichen Fehler, und es ist weniger als 19 Stellen. jede Idee, warum es wirft "Das wörtliche 0000007702062100L vom Typ lang ist außerhalb der Reichweite"
Santossh Kumhar
1
@ SantosshKumhar: Das ist ein oktales Literal , das keine Ziffern 8oder enthalten darf 9. Entfernen Sie die führenden Nullen.
Lukas Eder
49

Ich weiß nicht, warum es sich um den langen Datentyp als int handelt

Es ist nicht. Sie sollten lernen, Compiler-Nachrichten zu vertrauen (insbesondere, wenn sie von vernünftigen, modernen Compilern und nicht von alten C / C ++ - Compilern stammen). Während die Sprache, die sie sprechen, manchmal schwer zu entziffern ist, lügen sie dich normalerweise nicht an.

Schauen wir es uns noch einmal an:

Das Literal von int 9223372036854775807 liegt außerhalb des Bereichs.

Beachten Sie , dass es nicht der Fall ist Ihre Variable erwähnen testLongoder die Art longüberall, es ist also nicht über die Initialisierung. Das Problem scheint an einem anderen Punkt aufzutreten.

Lassen Sie uns nun einige Teile der Nachricht untersuchen:

  • intsagt uns, dass er etwas als intWert behandeln möchte (was nicht das ist, was Sie wollten!)
  • "außerhalb der Reichweite" ist ziemlich klar: etwas liegt nicht im erwarteten Bereich (wahrscheinlich der von int)
  • "Das Wörtliche": Nun, das ist interessant: Was ist ein Wörtlich?

Ich werde die gemütliche Liste verlassen, um einen Moment über Literale zu sprechen: Literale sind Orte, an denen Sie einen gewissen Wert in Ihrem Code haben. Es gibt StringLiterale, intLiterale, classLiterale und so weiter. Jedes Mal, wenn Sie einen Wert explizit in Ihrem Code erwähnen , handelt es sich um ein Literal.

Es nervt Sie also nicht wirklich an der Variablendeklaration, sondern an der Zahl selbst, der Wert ist das, worüber es Sie nervt.

Sie können dies leicht überprüfen, indem Sie dasselbe Literal in einem Kontext verwenden, in dem a longund an intgleichermaßen akzeptabel sind:

System.out.println(9223372036854775807);

PrintStream.printlnkann entweder einint oder einlong (oder so ziemlich alles andere) nehmen. Der Code sollte also in Ordnung sein, oder?

Nein . Nun, vielleicht ist es sollte sein, aber nach den Regeln es ist nicht in Ordnung.

Das Problem ist, dass "einige Ziffern" als intLiteral definiert sind und daher in dem durch definierten Bereich liegen müssenint .

Wenn Sie ein longLiteral schreiben möchten, müssen Sie dies explizit machen, indem Sie das L(oder Kleinbuchstaben) anhängen. lIch empfehle jedoch dringend , immer die Großbuchstabenvariante zu verwenden, da es viel einfacher zu lesen und schwerer mit a zu verwechseln ist 1.

Beachten Sie, dass ein ähnliches Problem bei float(postfix F/ f) und double(postfix D/ d) auftritt .

Randnotiz: Sie werden feststellen, dass es keine byteoder shortLiterale gibt und Sie können weiterhin Werte (normalerweise intLiterale) byteund shortVariablen zuweisen. Dies ist aufgrund spezieller Regeln in § 5.2 über Zuweisungskonverter möglich : Sie ermöglichen die Zuweisung von konstanten Ausdrücken eines größeren Typs auf byte, short, charoder int wenn die Werte innerhalb der Arten liegen.

Joachim Sauer
quelle
3
Wo nimmst du dir die Zeit von ;-)
Lukas Eder
3
@Lukas: Ich schreibe gelegentlich solche Antworten in der Hoffnung, dass ich nicht 300 kürzere Antworten dafür schreiben muss ;-) Außerdem bedeutet die Unterstützung bei der Interpretation der Fehlermeldung (hoffentlich) weniger "Was bedeutet diese Fehlermeldung?" - Fragen.
Joachim Sauer
Ihre Antwort ist sehr gut ... zweifellos, deshalb stimmen Sie ab, aber bitte bearbeiten Sie sie und schreiben Sie oben (Beginn Ihrer Antwort) einfach in 1 Zeile die genaue Lösung des Problems und dann unter Ihre Erklärung. Weil viele Leute eher nach einer schnellen Lösung als nach einer tiefen Erklärung
suchen
4
Sie können sich andere zweite Antworten ansehen (die am höchsten bewertete gibt sogar die schnelle Lösung). Ich denke, dass es auf lange Sicht nützlicher ist, Menschen darüber zu informieren, wie man Fehlermeldungen analysiert und versteht, als es nur für sie zu tun. "Gib einem Mann einen Fisch ..." und das alles.
Joachim Sauer
Danke für die Randnotiz.
Venkatesh Goud
17

Versuchen Sie es 9223372036854775807L. Das Lam Ende sagt Java, dass 9223372036854775807a long.

jontro
quelle
0

Ich hatte dieses Problem in der Vergangenheit und habe es behoben, indem ich den Wert in die wissenschaftliche Form geschrieben habe. beispielsweise:

double val = 9e300;

quelle
-2
long ak = 34778754226788444L/l;

Beide verwenden, aber jeweils nur einen Groß- oder Kleinbuchstaben l.

Warum L / L verwenden? Weil long ein Teil des integralen Datentyps ist.

Akkushwaha
quelle