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;

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


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.


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.


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;

-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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.