Специфікація номера L (довга) Java


95

Здається, коли ви вводите число в Java, компілятор автоматично читає його як ціле число, саме тому, коли ви вводите (long) 6000000000(не в діапазоні цілого числа), він скаржиться, що 6000000000це не ціле число. Щоб це виправити, мені довелося уточнити 6000000000L. Я щойно дізнався про цю специфікацію.

Чи існують інші специфікації номерів, такі як короткий, байт, плаваючий, подвійний? Здається, це було б добре мати, тому що (я припускаю), якщо б ви могли вказати номер, який ви вводите, короткий, тоді Java не повинен був би його кидати - це припущення, виправте мене, якщо я помиляюся . Зазвичай я б сам шукав це питання, але я не знаю, як взагалі називається така специфікація номерів.

Відповіді:


174

Існують специфічні суфікси для long(наприклад 39832L), float(наприклад 2.4f) та double(наприклад -7.832d).

Якщо суфікс відсутній, і це інтегральний тип (наприклад 5623), вважається, що це int. Якщо це не інтегральний тип (наприклад 3.14159), вважається, що це a double.

У всіх інших випадках ( byte, short, char), вам потрібно кидання , оскільки немає ніякого певного суфікса.

Специфікація Java допускає як суфікси верхнього, так і малого регістру, але longкраща версія верхнього регістру для s, оскільки верхній регістр Lменш легко сплутати з цифрою, 1ніж нижній регістр l.

Дивіться розділ 3.10 JLS для детальних відомостей (див. Визначення IntegerTypeSuffix).


9
Пізній вступ: усунення потенційних джерел двозначності - це завжди добре, і я не погоджуюсь ... але я вважаю, що якщо ви заплутаєтесь 1із lі 0з O(і так далі), вашим пріоритетом є правильне встановлення шрифту (якщо ви можете ), то турбуйтеся про те, щоб не пропустити клавішу Shift.
davidcsb

@SimonNickerson У мене запитання про суфікси ... Якщо я оголошую довгу або подвійну змінну типу: long _lo = 30;і чи не 30Lозначає це, що моя змінна буде перетворена в float ? Або у випадку, якщо _lo = _lo + 2.77це _loбуде кинуто в поплавок, хоча це було оголошено як довгий
luigi7up

Ні, поплавки тут не задіяні. У першому випадку, 30це an, intякий автоматично перетворюється за допомогою розширення перетворення в a long. У другому випадку ваша заява є незаконною. Вам доведеться явно кинути праву сторону на довгий час, наприклад_lo = (long) (_lo + 2.77)
Саймон Нікерсон,

4
Зміна шрифту @DavidCesarino виправляє для вас неоднозначність - у тому конкретному редакторі, де ви його правильно встановили. Зміна l на L усуває неоднозначність для всіх, хто може коли-небудь прочитати ваш код, включаючи вас самого, коли ви читаєте код в іншому редакторі, IDE, дивлячись на джерело в Інтернеті (інструменти перегляду, сховища тощо). Пріоритет IMHO - не пропустити клавішу Shift. До речі. який шрифт ти рекомендуєш? Мені подобається monospace, і це за замовчуванням майже у всіх редакторах, CLI тощо, що я бачив, і в цьому шрифті lта 1( 0і Oвідповідно) досить подібні.
dingalapadum

1
@dingalapadum Як я вже казав, ти маєш рацію. Видалення джерел двозначності - це, безумовно, правильна справа. Я просто сказав, що вам слід намагатися не використовувати будь-який редактор, де ви можете легко помилитися з ними. Іншими словами, стара пропозиція кодування оборонно, але не залежно від цього. Щодо шрифту, це дуже особисто, але я завжди використовую Deja Vu Sans Mono, коли тільки можу, оскільки 1) він має монопростір; 2) у нього немає двозначностей між символами; 3) Мені подобаються його форми, красиві та витончені, майже як хороший, читабельний шрифт без зарубок (інші гарні шрифти для програмування здаються занадто "металевими" IMHO).
davidcsb

13

Сподіваюсь, вам не завадить легкий дотик, але, можливо, вам буде цікаво дізнатись, що крім того F(для float), D(для double) та L(надовго) було внесено пропозицію додати суфікси для byteі short- Yі Sвідповідно . Це усуне необхідність приведення в байти при використанні буквального синтаксису для байтових (або коротких) масивів. Наводячи приклад із пропозиції:

ОСНОВНА ПЕРЕВАГА: Чому платформа краща, якщо пропозиція буде прийнята?

сирий код, як

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

можна перекодувати як

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

Джо Дарсі курує Project Coin для Java 7, і його блог став простим способом відстеження цих пропозицій.


це було б непогано ... Я завжди
виявляв,

Я вважаю, що це не потрапило в Java 7. Будь-яке слово про те, чи воно потрапить у майбутнє оновлення чи Java 8?
розчавити

@crush Я спробував вивчити це кілька місяців тому, і, наскільки я міг зрозуміти, від цієї пропозиції відмовились. 0bОднак ми отримали _ у числових літералах та префікс для двійкових літералів. Вуп.
erickson

Ці пропозиції, ймовірно, реалізовані на kotlin замість java, оскільки oracle не хоче, щоб спільнота розповідала їм, як працювати ... ми в 2018 році, і досі про цю пропозицію нічого, на жаль
JoelBonetR

11

За замовчуванням будь-який цілісний примітивний тип даних (byte, short, int, long) буде розглядатися компілятором Java як тип int . Для байтів і коротеньких , поки присвоєне їм значення знаходиться в їх діапазоні, немає проблем і не потрібен суфікс. Якщо значення, присвоєне байту та короткому, перевищує їх діапазон, потрібне явне приведення типу.

Наприклад:

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

для подолання цього виконують лиття типу.

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

У разі довгого типу даних він може приймати ціле значення без будь-яких клопотів. Припустимо, ми призначаємо як

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

в цьому випадку не потрібен суфікс типу L / l. За замовчуванням значення 2147483647 вважається компілятором Java типу int. Внутрішнє лиття типу виконується компілятором, а int автоматично підвищується до типу Long.

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

Тут нам потрібно поставити суфікс як L, щоб обробляти літерал 2147483648 як довгий тип за допомогою компілятора Java.

так нарешті

Long l = 2147483648L;// works fine.


1

Здається, їх було б добре мати, тому що (я припускаю), якби ви могли вказати номер, який ви вводите, короткий, тоді Java не довелося б його кидати

Оскільки розбір літералів відбувається під час компіляції, це абсолютно не має значення щодо продуктивності. Єдиною причиною наявності shortта byteсуфіксів було б добре, що це призводить до більш компактного коду.


0

Щоб зрозуміти , чому це необхідно розрізняти intі longлітерали, розглянути наступні питання:

long l = -1 >>> 1;

проти

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

Тепер, як ви справедливо очікували, обидва фрагменти коду надають змінному однакове значення l. Не маючи можливості розрізнити intі longлітерали, яке тлумачення -1 >>> 1?

-1L >>> 1 // ?

або

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

Отже, навіть якщо число знаходиться в загальному діапазоні, нам потрібно вказати тип. Якби значення за замовчуванням змінювалося з величиною літералу, тоді траплялися б дивні зміни в інтерпретації виразів лише від зміни цифр.

Це відбувається не для byte, shortа charтому, що їх завжди підвищують перед виконанням арифметичних та побітових операцій. Можливо, вони повинні бути цілочисельними суфіксами для використання, скажімо, у виразах ініціалізації масиву, але цього немає. floatвикористовує суфікс fі double d. Інші літерали мають однозначні типи, причому існує спеціальний тип для null.


Мені справді було б цікаво, що ви мали на увазі ще в ті часи. В обох випадках я отримую 2147483647, і я не розумію, чому мені слід очікувати чогось іншого.
Неймовірний

@TheincredibleJan Ви б справедливо очікували Integer.MAX_VALUE, однак, якби не було можливості розрізнити літерали intта longлітерали, це було б неоднозначно. / Я не пам’ятаю цього питання, але все одно пояснив свою відповідь.
Том Хоутін - таклін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.