Java 7 underscore in numeric literals

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

When we must use a _ to separate digits in a number I don't' understand the following case in which I can't use it:

In positions where a string of digits is expected

(as documented in the JDK7 guide here)

Some examples?

回答1:

You don't have to use "_", you can. And examples given in the proposal are credit card numbers, phone numbers, or simply numbers for which it makes sense to have a separator in the code.

For the "In positions where a string of digits is expected" it's simply in places where it's supposed to start (or end) with a digit. Here are some examples.

Note that according to this proposal, underscores can only be placed between digits. They cannot be placed by themselves in positions where a string of digits would normally be expected:

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)


Resources:



回答2:

As written in Javadoc:

In Java SE 7 and later, any number of underscore characters (_) can appear anywhere between digits in a numerical literal. This feature enables you, for example, to separate groups of digits in numeric literals, which can improve the readability of your code.

For instance, if your code contains numbers with many digits, you can use an underscore character to separate digits in groups of three, similar to how you would use a punctuation mark like a comma, or a space, as a separator.

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:

It looks like someone killed the URL in the original post (OP). Here's the whole nasty URL just in case some formatting feature kills it again:

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

The specific quote from that page to which you are speaking is as follows:

You can place underscores only between digits; you cannot place underscores in the following places:

  • At the beginning or end of a number

  • Adjacent to a decimal point in a floating point literal

  • Prior to an F or L suffix

  • In positions where a string of digits is expected

By the way, in an effort to be as persnickety as possible, it should be mentioned that for the third point, you can't use an underscore prior to the D suffix either, as shown in the following example:

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

I too found the third point rather curious. I mean, for the most part, all of the scenarios are covered by the first three points, so what is this mysterious 'string of digits' for which they speak? Which scenario doesn't actually get addressed by the first three points that forces them to add this mysterious fourth?

Initially I thought they were speaking about hexadecimal notation or binary notation, where a number is expected after the b or the x, as with the following examples that don't work:

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

Still, I think that might technically be the same as the first point, which says an underscore can't be at the beginning of the number; but certainly, a 'string of numbers' is expected after a 'b' or an 'x' when using binary or hex, right? So if I was a betting man, I might put some money behind the binary/hexadecimal scenario. But I have another plausible scenario on which I might hedge my bet. Here it goes.

Personally, I wish there was a rule in Java that said you can only use the word 'string' when talking about a java.lang.String. Allowing the term 'string' to retain it's pedestrian meaning causes confusion, and this is a perfect example.

Now, if the fourth point said "In positions where a java.lang.String of digits is expected" I might come to the conclusion that they're talking about actual java.lang.String objects that represent numbers that need to be parsed. So, take this piece of code:

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

Will that compile? Will that run? It will compile fine, but of course, the parseInt method expects a java.lang.String of numbers, and validation or parsing of that numeric java.lang.String will trigger the following error at runtime:

Exception in thread "main" java.lang.NumberFormatException: For input string: "123_456" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:492) at java.lang.Integer.parseInt(Integer.java:527) at Tester.main(Tester.java:7)

Of course, this is a runtime error, and it appears that the Oracle documentation is really speaking about errors that will be flagged at compile time. But this certainly is a scenario where a 'String of numbers' is expected.

Now if only the Oracle documentation was in a Wiki format. It might tempt me to go in and add something like the following:

You can place underscores only between digits; you cannot place underscores in the following places:

  • At the beginning or end of a number

  • Adjacent to a decimal point in a floating point literal

  • Prior to an 'F' or 'L' or 'D' suffix (I added the 'D')

  • Before or after the hexadecimal and binary markers 'x' and 'b'

  • And if you provide a java.lang.String to a method that expects nothing but numbers, expect a runtime exception to be thrown by the parsing algorithm that's being used behind the scenes.

By the way, I just wrote a little article on the topic over at TheServerSide. Feel free to take a look. The article is designed to hit on the Oracle Certified Professional, Java 7 Programmer certification objective, but it's a pretty comprehensive and easy to read article to just generally explain the rules around using underscores.

OCPJP Certification: What you need to know about numeric literals with underscores

Hope that helps.



回答4:

no idea, but here's the grammar, enjoy. (I don't see "string of digits" anywhere)

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:

My interpretation of this is that underscores cannot be placed by themselves in positions where a string of digits would normally be expected:

int x1= _; // Illegal. 


回答6:

I believe the "In positions where a string of digits is expected" covers things like escape sequences in string literals. For example, you can't say "\u00_11".



回答7:

"In positions where a string of digits is expected" means where a variable of type String which contains digits is expected, then using an underscore will make the underscore part of the number. For example look at the code below:

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

So if you have a method expecting a String of digits as one of the arguments, DO NOT use underscore to separate the digits because it will be treated as any other String.



回答8:

TL;TR;

You do not have to use it anywhere, but if you want, you can use it everywhere between every digits.

This is especially useful to improving readability:

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!