Specyfikacja numeru L (długiego) języka Java

96

Wygląda na to, że po wpisaniu liczby w Javie kompilator automatycznie odczytuje ją jako liczbę całkowitą, dlatego po wpisaniu (long) 6000000000(nie w zakresie całkowitoliczbowym) będzie narzekać, że 6000000000nie jest liczbą całkowitą. Aby to poprawić, musiałem określić 6000000000L. Właśnie dowiedziałem się o tej specyfikacji.

Czy istnieją inne specyfikacje liczbowe, takie jak short, byte, float, double? Wygląda na to, że dobrze byłoby je mieć, ponieważ (zakładam), gdybyś mógł określić numer, który wpisujesz, jest krótki, to java nie musiałby go przesyłać - to założenie, popraw mnie, jeśli się mylę . Zwykle sam bym przeszukał to pytanie, ale nie wiem, jak nazywa się tego rodzaju specyfikacja liczb.

jbu
źródło

Odpowiedzi:

177

Istnieją określone przyrostki dla long(np. 39832L), float(Np. 2.4f) I double(np -7.832d.).

Jeśli nie ma sufiksu i jest to typ całkowity (np. 5623), Zakłada się, że jest to int. Jeśli nie jest typem całkowitym (np. 3.14159), Zakłada się, że jest to typ double.

We wszystkich innych przypadkach ( byte, short, char), trzeba do obsady, ponieważ nie ma przyrostek specyficzny.

Specyfikacja języka Java zezwala na sufiksy wielkich i małych liter, ale longpreferowana jest wersja pisana dużymi literami dla s, ponieważ duże litery Lsą trudniejsze do pomylenia z liczbą 1niż małe l.

Więcej szczegółowych informacji można znaleźć w sekcji 3.10 JLS (patrz definicja IntegerTypeSuffix).

Simon Nickerson
źródło
9
Późne wejście: usuwanie potencjalnych źródeł dwuznaczność jest zawsze dobre, a ja nie zgadzam ... ale wierzę, że jeśli okaże się myli 1z li 0z O(i tak dalej), twój priorytetem jest ustalenie właściwej czcionki (jeśli potrafisz ), a następnie upewnij się, że nie przegapisz klawisza Shift.
davidcesarino
@SimonNickerson Mam pytanie o sufiksy ... Jeśli zadeklaruję zmienną długą lub podwójną typu: long _lo = 30;i 30Lczy nie oznacza to, że moja zmienna zostanie przekonwertowana na zmiennoprzecinkową ? Lub w przypadku _lo = _lo + 2.77, że _lobędą rzutować na pływaka mimo że został uznany za długo
luigi7up
Nie, pływaki nie są tutaj zaangażowane. W pierwszym przypadku 30jest to, intktóry jest automatycznie konwertowany poprzez konwersję poszerzającą do long. W drugim przypadku Twoje oświadczenie jest niezgodne z prawem. Musiałbyś wyraźnie rzucić prawą stronę za długą, np._lo = (long) (_lo + 2.77)
Simon Nickerson,
4
@DavidCesarino zmiana czcionki rozwiązuje dla Ciebie niejednoznaczność - w tym konkretnym edytorze, w którym ustawiłeś ją dobrze. Zmiana l na L rozwiązuje niejednoznaczność dla każdego, kto kiedykolwiek przeczytał twój kod, łącznie z tobą, gdy czytasz kod w innym edytorze, IDE, przeglądasz źródło w sieci (narzędzia do recenzji, repozytoria itp.). IMHO priorytetem jest nie przegapić klawisza Shift. Przy okazji. jaką czcionkę polecasz? Lubię monospace i jest to ustawienie domyślne prawie we wszystkich edytorach, CLI itp., Które widzę oraz w tej czcionce li 1( 0i Oodpowiednio) są dość podobne.
dingalapadum
1
@dingalapadum Jak powiedziałem, masz rację. Usunięcie źródeł niejasności jest zdecydowanie słuszne. Powiedziałem tylko, że powinieneś starać się nie używać żadnego edytora, w którym można łatwo je pomylić. Innymi słowy, stara sugestia kodowania obronnego, ale nie zależnego od tego. Jeśli chodzi o czcionkę, jest bardzo osobista, ale zawsze używam Deja Vu Sans Mono, kiedy tylko mogę, ponieważ 1) jest to czcionka o stałej szerokości; 2) nie ma niejednoznaczności między postaciami; i 3) Podoba mi się jego kształty, piękne i wdzięczne, prawie jak dobra, czytelna czcionka bezszeryfowa (inne dobre czcionki programistyczne wydają się zbyt „metaliczne” IMHO).
davidcesarino
13

Mam nadzieję, że nie będzie miał nic przeciwko niewielki stycznie, ale pomyślałem może być zainteresowany, aby wiedzieć, że oprócz F(dla pływaka), D(za podwójne), i L(na długo), wniosek został złożony , aby dodać do przyrostków bytei short- Yi Sodpowiednio . To wyeliminowałoby potrzebę rzutowania na bajty przy używaniu składni literału dla tablic bajtowych (lub krótkich). Cytując przykład z propozycji:

GŁÓWNA KORZYŚĆ: Dlaczego platforma jest lepsza, jeśli wniosek zostanie przyjęty?

brudny kod, taki jak

 byte[] stuff = { 0x00, 0x7F, (byte)0x80,  (byte)0xFF};

można przekodować jako

 byte[] ufum7 = { 0x00y, 0x7Fy, 0x80y, 0xFFy };

Joe Darcy nadzoruje Project Coin dla Java 7, a jego blog jest łatwym sposobem na śledzenie tych propozycji.

erickson
źródło
byłoby miło ... Zawsze uważałem, że wszystkie obsady są naprawdę irytujące
jbu,
Rozumiem, że to nie dotarło do Javy 7. Jakieś wieści o tym, czy trafi do przyszłej aktualizacji, czy do Javy 8?
zmiażdżyć
@crush Próbowałem się temu przyjrzeć kilka miesięcy temu i o ile mogłem stwierdzić, propozycja została porzucona. Otrzymaliśmy jednak _ w literałach numerycznych i 0bprzedrostek dla literałów binarnych. Wydać okrzyk radości.
erickson
Te propozycje są prawdopodobnie wdrażane na kotlinie zamiast na Javie, ponieważ wyrocznia nie chce, aby społeczność mówiła im, jak pracować ... jesteśmy na 2018 i niestety nadal nic o tej propozycji
JoelBonetR
11

Domyślnie każdy integralny pierwotny typ danych (bajt, krótki, int, długi) będzie traktowany jako typ int przez kompilator java. Dla bajt i zwarcia , o ile przypisana im wartość mieści się w ich zakresie, nie ma problemu i nie jest wymagany przyrostek. Jeśli wartość przypisana do bajtu i skrótu przekracza ich zakres, wymagane jest rzutowanie typu jawnego.

Dawny:

byte b = 130; // CE: range is exceeding.

aby przezwyciężyć rzucanie tego typu performansu.

byte b = (byte)130; //valid, but chances of losing data is there.

W przypadku długich typów danych może bez problemu przyjąć wartość całkowitą. Załóżmy, że przypiszemy coś podobnego

Long l = 2147483647; //which is max value of int

w tym przypadku nie jest wymagany przyrostek, taki jak L / l. Domyślnie wartość 2147483647 jest uważana przez kompilator java za typ int. Rzutowanie typu wewnętrznego jest wykonywane przez kompilator, a int jest automatycznie promowany do typu Long.

Long l = 2147483648; //CE: value is treated as int but out of range 

Tutaj musimy umieścić przyrostek jako L, aby traktować literał 2147483648 jako długi typ przez kompilator java.

więc w końcu

Long l = 2147483648L;// works fine.
Utpal Kumar
źródło
9

Są to literały i zostały opisane w sekcji 3.10 specyfikacji języka Java.

McDowell
źródło
1

Wygląda na to, że dobrze byłoby je mieć, ponieważ (zakładam), gdybyś mógł określić numer, który wpisujesz jest krótki, to java nie musiałby go przesyłać

Ponieważ parsowanie literałów odbywa się w czasie kompilacji, nie ma to absolutnie żadnego znaczenia w odniesieniu do wydajności. Jedynym powodem, dla którego posiadanie shorti byteprzyrostków byłoby fajne jest to, że prowadzi to do bardziej zwartego kodu.

Michael Borgwardt
źródło
0

Aby zrozumieć, dlaczego konieczne jest rozróżnienie między literami inta longliterałami, rozważ:

long l = -1 >>> 1;

przeciw

int a = -1;
long l = a >>> 1;

Jak można się słusznie spodziewać, oba fragmenty kodu nadają zmiennej tę samą wartość l. Nie będąc w stanie rozróżniać inti longdosłownie, jaka jest interpretacja -1 >>> 1?

-1L >>> 1 // ?

lub

(int)-1 >>> 1 // ?

Więc nawet jeśli liczba należy do wspólnego zakresu, musimy określić typ. Gdyby wartość domyślna zmieniła się wraz z wielkością literału, nastąpiłaby dziwna zmiana w interpretacji wyrażeń tylko po zmianie cyfr.

To nie wystąpić byte, shorta charponieważ są one zawsze promowane przed wykonaniem operacji arytmetycznych i bitowe. Prawdopodobnie powinny to być sufiksy typu całkowitego do użycia, powiedzmy, w wyrażeniach inicjujących tablice, ale tak nie jest. floatużywa przyrostka fi double d. Inne literały mają jednoznaczne typy, przy czym istnieje specjalny typ dla null.

Tom Hawtin - haczyk
źródło
Naprawdę byłbym zainteresowany tym, co miałeś na myśli w tamtych czasach. W obu przypadkach otrzymuję numer 2147483647 i nie rozumiem, dlaczego powinienem oczekiwać czegoś innego.
Niesamowity
@TheincredibleJan Słusznie byś się tego spodziewał Integer.MAX_VALUE, ale gdyby nie było sposobu na rozróżnienie między literami inta longliterałami, byłoby to niejednoznaczne. / Nie pamiętam tego pytania, ale i tak wyjaśniłem swoją odpowiedź.
Tom Hawtin - tackline