Java 7 underscore in numeric literals
Solution 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:
- OpenJDK - Project Coin - PROPOSAL: Underscores in Numbers (Version 2)
- Joe Darcy's blog - Project Coin: Project Coin: Literal Grammar Hackery
Solution 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;
Solution 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.
Solution 4:
TL;TR;
You do not have to use it anywhere, but if you want, you can use it everywhere between every digit in numeric literals.
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