Why use Underscore in Numbers from Java SE 7 - Underscore in Numeric Literals

JDK 1.7 release had introduced several useful features, despite most of them being syntactic sugar, there use can greatly improve readability and code quality. One of such feature is introduction of underscore in numeric literals. From Java 7 onwards you can write a long digit e.g. 10000000000 to a more readable 10_000_000_000 in your Java source code. One of the most important reason of using underscore in numeric literal is avoiding subtle mistakes which is hard to figure out by looking at code. It's hard to notice a missing zero or extra zero between 10000000000 and 1000000000, than 10_000_000_000 and 1_000_000_000.

So, if you are dealing with big numbers in Java  source code, use underscore in numbers to improve readability.

By the way, there are rules to use underscore in numeric literals, as they are also a valid character in identifier, you can only use them in between digits, precisely neither at the start of numeric literal nor at the end of numeric literals.

In next couple of section, we will learn how underscore in numeric literal is implemented and rules to use them in numerical literals.

How underscore in numbers are implemented in Java

As I said that it's a syntactic sugar, much like how String in switch case is implemented, this is also implemented using help of compiler. At compile time, compiler removes these underscore and put actual number into variable. For example 10_000_000 will be converted into 10000000 during compile time.

Since CPU has no problem dealing with long String of digits and it's fun for him, we don't bother about that, it's us, poor humans which has problem dealing with longer numbers.  This feature is particularly useful for banking and finance domain application, which deals with large sum of money, credit card number, bank account numbers and other domains, which deals with longer ids.

Though it's strongly discouraged to write sensitive data in Java files and you should never do in production code, life is much easier with underscore in numbers than before.

Rules to use underscore in numbers in Java

JDK 7 Underscore in Numeric literals
Java programming language has strict set of rules towards usage of underscore in numeric literals. As stated, you can only use them in between digits. You can not start a number by underscore, or end a number by underscore. Here are some more places, where you just can not place underscore in numeric literals :

1) At the beginning or end of a number
2) Adjacent to a decimal point in a floating point literal
3) Prior to an F or L suffix
4) In positions where a string of digits is expected

Here are couple of examples, which shows some valid and invalid usage of underscore in numeric literals

float pi1 = 3_.1415F;      // Invalid; cannot put underscores adjacent (before) to a decimal point
float pi2 = 3._1415F;      // Invalid; cannot put underscores adjacent (after) to a decimal point
long socialSecurityNumber1  = 999_99_9999_L;  // Invalid; cannot put underscores prior to an L suffix

int a1 = _52;              // This is an identifier, not a numeric literal, starts with underscore
int a2 = 5_2;              // OK (decimal literal)
int a3 = 52_;              // Invalid; cannot put underscores at the end of a literal
int a4 = 5_______2;        // OK (decimal literal)

int a5 = 0_x52;            // Invalid; cannot put underscores in the 0x radix prefix
int a6 = 0x_52;            // Invalid; cannot put underscores at the beginning of a number
int a7 = 0x5_2;            // OK (hexadecimal literal)
int a8 = 0x52_;            // Invalid; cannot put underscores at the end of a number

int a9 = 0_52;             // OK (octal literal)
int a10 = 05_2;            // OK (octal literal)
int a11 = 052_;            // Invalid; cannot put underscores at the end of a number

Here are some more examples of using underscore in numeric literals

long creditCardNumber = 6684_5678_9012_3456L;  // Never do it on production code
long socialSecurityNumber = 333_99_9999L;      // Never, Ever do it on production code
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;

You can see that code is much more readable than without using underscore in numbers. By the way, always use L to denote a long literal in Java. Though it's legal to use small case l, you should never use it with numbers as it looks exactly similar to digit 1. Tell me if you can find out differences between 12l and 121, I guess not many. How about 12L and 121?

In short, always use underscore in numbers, especially with long numbers to make them more readable. I know this feature is only available from Java 1.7, and it's not widely used yet, but given Java 8 profile, I am expected that, Java 8 will be adopted by community more quickly and widely than Java 7.


Anonymous said...

long creditCardNumber = 6684_5678_9012_3456L;
why have you asked to never use the above on the production code ?? what does that mean??

Anonymous said...

The warning is against hard-coding credit card numbers and social security numbers in production code.

Post a Comment