Спецификация числа L Java (длинная)

96

Похоже, что когда вы вводите число в Java, компилятор автоматически считывает его как целое число, поэтому, когда вы вводите (long) 6000000000(не в целочисленном диапазоне), он будет жаловаться, что 6000000000это не целое число. Чтобы исправить это, мне пришлось уточнить 6000000000L. Я только что узнал об этой спецификации.

Существуют ли другие спецификации чисел, такие как short, byte, float, double? Похоже, их было бы хорошо иметь, потому что (я полагаю), если бы вы могли указать номер, который вы вводите, короткий, тогда java не пришлось бы его приводить - это предположение, поправьте меня, если я ошибаюсь . Обычно я сам ищу этот вопрос, но я не знаю, как вообще называется такая спецификация числа.

jbu
источник

Ответы:

174

Существуют специальные суффиксы для long(например 39832L), float(например 2.4f) и double(например -7.832d).

Если суффикса нет и это целочисленный тип (например, 5623), предполагается, что это int. Если это не интегральный тип (например 3.14159), предполагается, что это double.

Во всех остальных случаях ( byte, short, char), вам нужно бросание , поскольку нет никакого определенного суффикса.

Спецификация Java допускает суффиксы как в верхнем, так и в нижнем регистре, но для longs предпочтительнее использовать верхний регистр, так как верхний регистр Lлегче спутать с цифрой, 1чем нижний регистр l.

См. Подробности в разделе 3.10 JLS (см. Определение IntegerTypeSuffix).

Саймон Никерсон
источник
9
Поздняя запись: устранение потенциальных источников неопределенности всегда хорошо, и я не согласен ... но я верю , что если вы оказываетесь в заблуждение 1с lи 0с O(и так далее), ваш приоритет должен установить правильный шрифт (если вы можете ), затем позаботьтесь о том, чтобы не пропустить клавишу Shift.
davidcesarino
@SimonNickerson У меня вопрос о суффиксах ... Если я объявлю переменную типа long или double, например:, long _lo = 30;а не 30Lозначает ли это, что моя переменная будет преобразована в число с плавающей запятой ? Или в случае _lo = _lo + 2.77этого _loбудет брошен в плавание, хотя это было объявлено длинным
luigi7up
Нет, поплавки здесь не задействованы. В первом случае 30это объект, intкоторый автоматически конвертируется с помощью расширяющего преобразования в long. Во втором случае ваше утверждение незаконно. Вам нужно будет явно сделать длинную правую часть, например_lo = (long) (_lo + 2.77)
Саймон Никерсон
4
@DavidCesarino изменение шрифта устраняет двусмысленность для вас - в том конкретном редакторе, где вы установили его правильно. Изменение l на L устраняет двусмысленность для всех, кто может когда-либо читать ваш код, включая вас самих, когда вы читаете код в другом редакторе, IDE, просматриваете исходный код в Интернете (инструменты просмотра, репозитории и т. Д.). ИМХО приоритет - не пропустить клавишу Shift. Кстати. какой шрифт посоветуете? Мне нравится моноширинный шрифт, и он используется по умолчанию почти во всех редакторах, интерфейсах командной строки и т.д., которые я видел, и в этом шрифте lи 1( 0и Oсоответственно) они довольно похожи.
dingalapadum
1
@dingalapadum Как я уже сказал, ты прав. Устранение источников двусмысленности, безусловно, правильное решение. Я просто сказал, что вы должны стараться не использовать какой-либо редактор, в котором вы легко можете ошибиться. Другими словами, старое предложение кодировать в целях защиты, но не в зависимости от этого. Что касается шрифта, это очень личное, но я всегда использую Deja Vu Sans Mono, когда могу, потому что 1) он моноширинный; 2) в нем нет двусмысленности между персонажами; и 3) Мне нравятся его формы, красивые и изящные, почти как хороший читаемый шрифт без засечек (другие хорошие программные шрифты кажутся слишком "металлическими" ИМХО).
davidcesarino
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
@crush Я попытался изучить это несколько месяцев назад, и, насколько я мог судить, предложение было отклонено. Однако мы получили _ в числовых литералах и 0bпрефикс для двоичных литералов. Ой.
erickson
Эти предложения, вероятно, реализованы на kotlin вместо java, поскольку oracle не хочет, чтобы сообщество рассказывало им, как работать ... мы находимся в 2018 году, но, к сожалению, ничего не об этом предложении
JoelBonetR
11

По умолчанию любой интегральный примитивный тип данных (byte, short, int, long) будет рассматриваться компилятором java как тип int . Для byte и short , пока присвоенное им значение находится в их диапазоне, проблем нет и суффикс не требуется. Если значение, присвоенное byte и short, превышает их диапазон, требуется явное приведение типа.

Пример:

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, чтобы компилятор java рассматривал литерал 2147483648 как длинный тип.

так что наконец

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.

Том Хотин - tackline
источник
Мне действительно было бы интересно, что вы имели в виду в те дни. В обоих случаях я получаю 2147483647 и не понимаю, почему я должен ожидать чего-то другого.
Невероятное
@TheincredibleJan Как и следовало ожидать Integer.MAX_VALUE, если бы не было возможности отличить литералы от intи, longэто было бы неоднозначно. / Я не помню этот вопрос, но все равно пояснил свой ответ.
Том Хотин - tackline