Obecnie pracuję z typami danych w Javie i jeśli dobrze zrozumiałem, typ long
przyjmuje 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 long
zmienną 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 long
typu 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;
java
int
long-integer
Mathew Donnan
źródło
źródło
Odpowiedzi:
Dodaj kapitał
L
na koniec:long value = 9223372036854775807L;
W przeciwnym razie kompilator spróbuje przeanalizować literał jako an
int
, stąd komunikat o błędzieźródło
8
ani9
. Usuń wiodące zera.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:
Zauważ, że to nie wspominając o zmiennej
testLong
lub typulong
wszędzie, więc to nie o inicjalizacji. Wydaje się, że problem pojawia się w innym miejscu.Teraz zbadajmy niektóre części wiadomości:
int
mówi nam, że chce traktować coś jakoint
wartość (która nie jest tym, czego chciałeś!)int
)Zostawię przytulną listę, aby porozmawiać przez chwilę o literałach: literały to miejsca, w których masz jakąś wartość w swoim kodzie. Istnieją
String
literały,int
literały,class
literał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
long
i anint
są równie dopuszczalne:System.out.println(9223372036854775807);
PrintStream.println
można wziąć albo lub (lub prawie nic innego). Więc ten kod powinien być w porządku, prawda?int
long
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
int
dosłowne i dlatego muszą znajdować się w zakresie określonym przezint
.Jeśli chcesz napisać
long
literał, musisz to wyraźnie zaznaczyć, dodającL
(lub małe literyl
, ale zdecydowanie sugeruję, abyś zawsze używał wariantu z dużymi literami , ponieważ jest znacznie łatwiejszy do odczytania i trudniejszy do pomylenia z a1
).Zauważ, że podobny problem występuje z
float
(postfixF
/f
) idouble
(postfixD
/d
).Uwaga boczna: zdasz sobie sprawę, że nie ma żadnych literałów
byte
lubshort
i nadal możesz przypisywać wartości (zwykleint
literały) dobyte
ishort
zmiennym: 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 dobyte
,short
,char
lubint
jeśli wartości są w zasięgu typy.źródło
Spróbuj
9223372036854775807L
. NaL
końcu mówi Javie, że9223372036854775807
jest to pliklong
.źródło
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
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.
źródło