Literał xyz typu int jest poza zakresem

90

Obecnie pracuję z typami danych w Javie i jeśli dobrze zrozumiałem, typ longprzyjmuje wartość z zakresu od -9 223 372 036 854 775 808 do +9 223 372 036 854 775 807. Teraz jak widać poniżej utworzyłem longzmienną o nazwie testLong, chociaż jak wstawiam 9223372036854775807 jako wartość to wyskakuje mi błąd o treści:

Dosłowny 9223372036854775807 typu int jest poza zakresem.

Nie wiem, dlaczego odnosi się do longtypu danych jako int.

Czy ktoś ma jakieś pomysły?

Kod:

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
źródło
Przy okazji: jakiego kompilatora używasz? Zarówno Eclipse, jak i kompilator Sun JDK podają różne (moim zdaniem lepsze) komunikaty o błędach dla tego problemu.
Joachim Sauer

Odpowiedzi:

196

Dodaj kapitał Lna koniec:

long value = 9223372036854775807L;

W przeciwnym razie kompilator spróbuje przeanalizować literał jako an int, stąd komunikat o błędzie

Lukas Eder
źródło
4
Jest w specyfikacji języka Java. Znajdź pełny tekst tutaj
Lukas Eder,
@Lukas, długa wartość = 00000077029062100L; daje mi ten sam błąd i ma mniej niż 19 cyfr. jakikolwiek pomysł, dlaczego rzuca „Dosłowne 0000007702062100L typu long jest poza zasięgiem”
Santossh Kumhar
1
@SantosshKumhar: To jest literał ósemkowy , który nie może zawierać cyfr 8ani 9. Usuń wiodące zera.
Lukas Eder
51

Nie wiem, dlaczego odnosi się do typu danych long jako int

Nie jest. Powinieneś nauczyć się ufać komunikatom kompilatora (zwłaszcza, gdy pochodzą one od rozsądnych, nowoczesnych kompilatorów, a nie starożytnych kompilatorów C / C ++). Chociaż język, którym mówią, może być czasami trudny do rozszyfrowania, zwykle nie kłamią.

Spójrzmy na to jeszcze raz:

Literał int 9223372036854775807 jest poza zakresem.

Zauważ, że to nie wspominając o zmiennej testLonglub typu longwszędzie, więc to nie o inicjalizacji. Wydaje się, że problem pojawia się w innym miejscu.

Teraz zbadajmy niektóre części wiadomości:

  • intmówi nam, że chce traktować coś jako intwartość (która nie jest tym, czego chciałeś!)
  • „poza zasięgiem” jest całkiem jasne: coś nie mieści się w oczekiwanym zakresie (prawdopodobnie z int)
  • „Dosłowne”: to interesujące: co to jest dosłowne?

Zostawię przytulną listę, aby porozmawiać przez chwilę o literałach: literały to miejsca, w których masz jakąś wartość w swoim kodzie. Istnieją Stringliterały, intliterały, classliterały i tak dalej. Za każdym razem, gdy wyraźnie wymieniasz wartość w swoim kodzie, jest to literał.

Więc tak naprawdę nie dręczy cię deklaracja zmiennej, ale sama liczba, wartość jest tym, o co cię dręczy.

Możesz to łatwo sprawdzić, używając tego samego literału w kontekście, w którym a longi an intsą równie dopuszczalne:

System.out.println(9223372036854775807);

PrintStream.printlnmożna wziąć albo lub (lub prawie nic innego). Więc ten kod powinien być w porządku, prawda?intlong

Nie. Może powinno być, ale zgodnie z zasadami nie jest w porządku.

Problem polega na tym, że „niektóre cyfry” są zdefiniowane jako intdosłowne i dlatego muszą znajdować się w zakresie określonym przez int.

Jeśli chcesz napisać longliterał, musisz to wyraźnie zaznaczyć, dodając L(lub małe litery l, ale zdecydowanie sugeruję, abyś zawsze używał wariantu z dużymi literami , ponieważ jest znacznie łatwiejszy do odczytania i trudniejszy do pomylenia z a 1).

Zauważ, że podobny problem występuje z float(postfix F/ f) i double(postfix D/ d).

Uwaga boczna: zdasz sobie sprawę, że nie ma żadnych literałów bytelub shorti nadal możesz przypisywać wartości (zwykle intliterały) do bytei shortzmiennym: jest to możliwe dzięki specjalnym regułom w § 5.2 dotyczącym konwersji przypisania : pozwalają one na przypisanie stałych wyrażeń większego typu do byte, short, charlub int jeśli wartości są w zasięgu typy.

Joachim Sauer
źródło
3
Skąd bierzesz czas ;-)
Lukas Eder
3
@Lukas: Od czasu do czasu piszę takie odpowiedzi w nadziei, że nie będę musiał pisać za to 300 krótszych ;-) Ponadto: pomoc w interpretacji komunikatu błędu (miejmy nadzieję) oznacza mniej pytań "co oznacza ten komunikat błędu".
Joachim Sauer
twoja odpowiedź jest bardzo dobra ... bez wątpienia, dlatego głosuj pozytywnie, ale edytuj ją i na górze (początek odpowiedzi) wpisz w jednej linii dokładne rozwiązanie problemu, a następnie poniżej wyjaśnienia. Ponieważ wiele osób szuka szybkiego rozwiązania, a nie głębokiego wyjaśnienia
Shirish Herwade
4
Mogą swobodnie przeglądać inne drugie odpowiedzi (ta z największą liczbą głosów daje nawet szybkie rozwiązanie). Myślę, że uczenie ludzi, jak analizować i rozumieć komunikaty o błędach, jest bardziej przydatne na dłuższą metę niż robienie tego za nich. „Daj człowiekowi rybę…” i tak dalej.
Joachim Sauer
Dzięki za uwagę.
Venkatesh Goud
19

Spróbuj 9223372036854775807L. Na Lkońcu mówi Javie, że 9223372036854775807jest to plik long.

jontro
źródło
0

Miałem ten problem w przeszłości i naprawiłem go, zapisując wartość w formie naukowej. na przykład:

double val = 9e300;

źródło
-2
long ak = 34778754226788444L/l;

Oba używają, ale jednocześnie tylko jedna duża litera L lub mała litera l.

Dlaczego używać L / l? Ponieważ long jest częścią integralnego typu danych.

Akkushwaha
źródło