Знак подчеркивания Java 7 в числовых литералах

Когда мы должны использовать _ для разделения цифр в номере, я не понимаю следующий случай, когда я не могу его использовать:

В позициях, где ожидается строка цифр

(как описано в руководстве JDK7 здесь)

Некоторые примеры?

Ответ 1

У вас нет, чтобы использовать "_", вы можете. Примерами, приведенными в предложении, являются номера кредитных карт, номера телефонов или просто номера, для которых имеет смысл иметь разделитель в коде.

Для "В позициях, где ожидается строка цифр", он просто в местах, где он должен начинаться (или заканчиваться) цифрой. Вот несколько примеров.

Обратите внимание, что в соответствии с этим предложением подчеркивания могут быть помещены только между цифрами. Они не могут быть размещены сами по себе в тех местах, где обычно ожидается строка цифр:

int x1 = _52; //This is an identifier, not a numeric literal.

int x2 = 5_2; //OK. (Decimal literal)

int x2 = 52_; //Illegal. (Underscores must always be between digits)

int x3 = 5_______2;//OK. (Decimal literal.)

int x4 = 0_x52; //Illegal. Can't put underscores in the "0x" radix prefix.

int x5 = 0x_52; //Illegal. (Underscores must always be between digits)

int x6 = 0x5_2; //OK. (Hexadecimal literal)

int x6 = 0x52_; //Illegal. (Underscores must always be between digits)

int x6 = 0x_; //Illegal. (Not valid with the underscore removed)

int x7 = 0_52; //OK. (Octal literal)

int x7 = 05_2; //OK. (Octal literal)

int x8 = 052_; //Illegal. (Underscores must always be between digits)


Ресурсы:

Ответ 2

Как написано в Javadoc:

В Java SE 7 и более поздних версиях любое количество символов подчеркивания (_) может появляются где-нибудь между цифрами в числовом литерале. Эта особенность позволяет вам, например, разделять группы цифр в числовом литералы, которые могут улучшить читаемость вашего кода.

Например, если ваш код содержит цифры со многими цифрами, вы можете используйте символ подчеркивания для разделения цифр в группах по три, подобно тому, как вы будете использовать знак препинания, как запятую, или пространство, как разделитель.

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi =  3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

Ответ 3

Похоже, кто-то убил URL-адрес в исходном сообщении (OP). Здесь весь неприятный URL-адрес на всякий случай, когда какая-то функция форматирования снова убивает его:

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Конкретная цитата с той страницы, на которую вы говорите, выглядит следующим образом:

Вы можете разместить символы подчеркивания только между цифрами; вы не можете размещать символы подчеркивания в следующих местах:

  • В начале или конце номера

  • Рядом с десятичной точкой в ​​литерале с плавающей запятой

  • До суффикса F или L

  • В позициях, где ожидается строка цифр

Кстати, чтобы быть как можно более проницаемым, следует упомянуть, что для третьего пункта вы не можете использовать символ подчеркивания до суффикса D, как показано в следующем примере:

double trouble = 123.456_D;  //fail
float myBoat = 321.123_F;  //fail
long winded = 90210_L;  //fail

Я тоже нашел третий пункт довольно любопытным. Я имею в виду, по большей части, все сценарии охвачены первыми тремя моментами, так что это за таинственная "строка цифр", за которую они говорят? Какой сценарий на самом деле не решаются первыми тремя моментами, которые заставляют их добавить эту загадочную четверть?

Первоначально я думал, что они говорят о шестнадцатеричной нотации или двоичной нотации, где число ожидается после b или x, как со следующими примерами, которые не работают:

byte size = 0_b111101;  //fail
byte me = 0b_111101;  //fail
int hexed = 0_x_BABE;  //fail

Тем не менее, я думаю, что это технически может совпадать с первым пунктом, в котором подчеркивается, что подчеркивание не может быть в начале числа; но, конечно, "строка чисел" ожидается после "b" или "x" при использовании двоичного или шестнадцатеричного, правильно? Поэтому, если бы я был игроком ставок, я мог бы положить немного денег за двоичный/шестнадцатеричный сценарий. Но у меня есть еще один правдоподобный сценарий, по которому я мог бы хеджировать свою ставку. Вот оно.

Лично мне жаль, что на Java не было правила, в котором говорилось, что вы можете использовать слово "строка", когда речь идет о java.lang.String. Предоставление термину "строка" сохранить его значение для пешехода вызывает путаницу, и это прекрасный пример.

Теперь, если четвертый пункт сказал "В позициях, где ожидается java.lang.String цифр", я могу прийти к выводу, что они говорят о реальных объектах java.lang.String, которые представляют числа, которые должны анализироваться. Итак, возьмите этот фрагмент кода:

int i = Integer.parseInt("123_456");

Будет ли это компилироваться? Будет ли это работать? Он будет компилироваться отлично, но, конечно, метод parseInt ожидает java.lang.String чисел, а проверка или разбор этого числового java.lang.String вызовет следующую ошибку во время выполнения:

Исключение в потоке "main" java.lang.NumberFormatException: для ввода строка: "123_456" на java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) в java.lang.Integer.parseInt(Integer.java:492) в java.lang.Integer.parseInt(Integer.java:527)         на Tester.main(Tester.java:7)

Конечно, это ошибка времени выполнения, и похоже, что документация Oracle действительно говорит об ошибках, которые будут отмечены во время компиляции. Но это, безусловно, сценарий, где ожидается "строка чисел".

Теперь, если только документация Oracle была в формате Wiki. Это может соблазнить меня войти и добавить что-то вроде следующего:

Вы можете разместить символы подчеркивания только между цифрами; вы не можете размещать символы подчеркивания в следующих местах:

  • В начале или конце номера

  • Рядом с десятичной точкой в ​​литерале с плавающей запятой

  • До суффикса 'F' или 'L' или 'D' (я добавил 'D')

  • До или после шестнадцатеричных и двоичных маркеров "x" и "b"

  • И если вы предоставите java.lang.String методу, который не ожидает ничего, кроме чисел, ожидайте, что исключение во время выполнения будет выбрано алгоритмом синтаксического анализа, который используется за кулисами.

Кстати, я только что написал небольшую статью по этой теме на TheServerSide. Не стесняйтесь смотреть. Статья предназначена для достижения цели сертификации Certified Professional, Java 7 Programmer, но это довольно всеобъемлющая и легко читаемая статья, чтобы просто объяснить правила вокруг использования символов подчеркивания.

Сертификация OCPJP: что вам нужно знать о числовых литералах с символами подчеркивания

Надеюсь, что это поможет.

Ответ 4

Не знаю, но вот грамматика, наслаждайся. (Я нигде не вижу "строки цифр" )

http://download.oracle.com/otndocs/jcp/enhancements-0.875-pr-oth-JSpec/

IntegerLiteral:
    DecimalIntegerLiteral 
    HexIntegerLiteral 
    OctalIntegerLiteral 
    BinaryIntegerLiteral 

BinaryIntegerLiteral:
    BinaryNumeral IntegerTypeSuffixopt 

BinaryNumeral:
    0 b BinaryDigits 
    0 B BinaryDigits 

DecimalNumeral:
    0 
    NonZeroDigit Digitsopt 
    NonZeroDigit Underscores Digits 

Underscores:
    _ 
    Underscores _ 

Digits:
    Digit
    Digit DigitsAndUnderscoresopt Digit

DigitsAndUnderscores:
    DigitOrUnderscore
    DigitsAndUnderscores DigitOrUnderscore

DigitOrUnderscore:
    Digit
    _

HexDigits:
    HexDigit 
    HexDigit HexDigitsAndUnderscoresopt HexDigit 

HexDigitsAndUnderscores:
    HexDigitOrUnderscore 
    HexDigitsAndUnderscores HexDigitOrUnderscore 

HexDigitOrUnderscore:
    HexDigit 
    _ 

OctalNumeral:
    0 OctalDigits 
    0 Underscores OctalDigits 

OctalDigits:
    OctalDigit 
    OctalDigit OctalDigitsAndUnderscoresopt OctalDigit 

OctalDigitsAndUnderscores:
    OctalDigitOrUnderscore 
    OctalDigitsAndUnderscores OctalDigitOrUnderscore 

OctalDigitOrUnderscore:
    OctalDigit 
    _ 

BinaryDigits:
    BinaryDigit 
    BinaryDigit BinaryDigitsAndUnderscoresopt BinaryDigit 

BinaryDigitsAndUnderscores:
    BinaryDigitOrUnderscore 
    BinaryDigitsAndUnderscores BinaryDigitOrUnderscore 

BinaryDigitOrUnderscore:
    BinaryDigit
    _ 

BinaryDigit: one of
    0 1

Ответ 5

Моя интерпретация этого заключается в том, что подчеркивания не могут быть помещены сами по себе в положениях, где обычно ожидается строка цифр:

int x1= _; // Illegal.

Ответ 6

Я считаю, что В позициях, где ожидается строка цифр, охватывает такие вещи, как escape-последовательности в строковых литералах. Например, вы не можете сказать \u00_11.

Ответ 7

"В положениях, где ожидается строка цифр" означает, что ожидается переменная типа String, которая содержит цифры, а затем подчеркивание сделает подчеркивание частью числа. Например, посмотрите на код ниже:

int num = 999_333;    
String anum = "999_333";
System.out.println(num);   //Outputs 999333
System.out.println(anum);  //Outputs 999_333

Итак, если у вас есть метод, ожидающий строки цифр в качестве одного из аргументов, НЕ используйте знак подчеркивания для разделения цифр, потому что он будет рассматриваться как любая другая строка.

Ответ 8

TL; ТР;

Вы не должны использовать его в любом месте, но если вы хотите, , вы можете использовать его везде между любыми цифрами.

Это особенно полезно для повышения удобочитаемости:

10_000_000_000 // Is equal to 10000000000
7_687_316_418_138_483.345_938 // Is equal to 7687316418138483.345938