You are currently viewing Where To Use the Underscore in Java

Where To Use the Underscore in Java

What you are reading is one in a series of articles titled “Stranger things in Java”, inspired by the contents of my book “Java for Aliens”. These articles are dedicated to insights of the Java language. Deepening the topics we use every day, will allow us to master the Java coding even in the strangest scenario.

In this article we will try to clarify the use of the underscore symbol_” in Java programming. So, let’s examine the use cases of this symbol within a Java program. Let’s start with the best-known case.

 

Underscore and Identifiers

We know that it is possible to use the underscore symbol as part of an identifier of a programming element. In fact to define an identifier in Java, we can use:

  • Uppercase and lowercase letters
  • Numbers (but not at the beginning of the identifier)
  • The dollar sign ‘$’ (which, however, is practically never used)
  • The underscore symbol ‘_

However, the standard conventions for defining the identifiers of variables, methods, Java types (classes, interfaces, enumerations, records and annotations), packages and modules, do not require the use of the underscore symbol. In Java programming, only the standard convention for constant identifiers requires the use of the underscore symbol. In fact, this convention recommends defining names consisting of uppercase characters only, and using the underscore symbol as a word separator to improve readability. For instance:

final int SIDES_NUMBER_OF_SQUARE = 4;
final double PI = 3.14;

This is because a constant must be easily recognizable, and by using all capital characters the developer is able to distinguish the constants from the variables at a glance.

 

New in Java 8

Up to version 8 of Java it was even possible to use just one underscore symbol as the identifier of a Java programming element, such as a variable or a method. In version 8, however, the compiler already issued a warning in order to not use this practice. In fact, if we tried to define for example a variable like this with Java 8:

int _;

the code compiled correctly, but this warning was printed:

warning: '_' used as an identifier
        int _;
            ^
(use of '_' as an identifier might not be supported in releases after Java SE 8)
1 warning

which warned us that the use of the underscore symbol as an identifier may no longer be supported in future versions.

 

New in Java 9

In fact, if we try to compile the previous code with a version higher than 8, we will directly get the following compilation error:

error: as of release 9, ‘_‘ is a keyword, and may not be used as an identifier

error: as of release 9, '_' is a keyword, and may not be used as an identifier
        int _;
            ^
1 error

which warns us that since version 9 it is no longer possible to use a single underscore as an identifier.

Note that in this compiler message the underscore is defined as a keyword, which is not entirely correct. A keyword in Java has a very specific meaning, such as class, while or instanceof. It would be more appropriate to define underscore as a reserved word, that is a word that has no particular meaning for Java syntax, but which cannot be used as a method identifier. The other reserved words defined by the language are goto and const, which actually have no meaning for Java syntax, but are not accepted by the compiler as identifiers.

However, it is possible to use two or more consecutive underscores as an identifier without any problems. In fact, the following declaration is compiled without errors:

int __;

 

Underscore for Numeric Types Literals

From version 7 of Java, to improve the readability of the values assigned to our numeric variables, it is also possible to use underscores. For example, the following statement

int i = 1000000000;

can be rewritten as follows:

int i = 1_000_000_000;

making it clear that the value of the variable i is worth one billion.

Underscore can also be used to improve the readability of numeric types written with other notations. For example, the following declaration using binary notation marked with the prefix 0b (or 0B):

int bytes = 0b10100001010001011010000101000101;

can be rewritten by separating the various bytes with underscores:

int bytes = 0b10100001_01000101_10100001_01000101;

It is clear that the use of underscore guarantees greater readability of our numerical values.

 

Other Notations for Integer Types

We can also represent an integer in hexadecimal format marked by the prefix 0x (or 0X):

long maxLong = 0x7fff_ffff_ffff_ffffL;

Or even an integer in octal format, for example separating the prefix 0 that characterizes this notation from the octal number, which often confuses the ideas of the developer. Indeed:

int octal = 052;

it is actually an octal number which when converted as a decimal number is 42! Rewriting it like this:

int octal = 0_52;

we will be less likely to get confused.

We can theoretically use sequences of multiple adjacent underscores:

int octal = 0__________52;

 

Underscore for Floating Point Numeric Types

We can use the underscore symbol also for the floating point numeric types float and double identifiers. For example:

final float PI = 3.14_15F;

or:

double d = 0.000_000_001;

It is also possible to use exponential or engineering notation characterized by the use of the letter ‘e‘ (which can be both upper and lower case). For example:

double d = 0.260_174E-2; //equivalent to 0.260174 divided by 100 = 0.00260174

 

One Rule to Remember

There is only one rule to respect in order to correctly use underscores with numeric data types:

  • You can use one or more underscores only between two numbers

For example, the following statements are not valid:

final float PI_1 = 3_.1415F;
final double PI_2 = 3._1415D;
long socialSecurityNumber  = 999_99_9999_L;
int x1 = _52;
int x2 = 52_;
int x3 = 0_x52;
int x4 = 0x_52;
int x5 = 0x52_;

Notice that the octal declaration we saw earlier:

int octal = 0_52;

it is valid as the prefix does not contain a character, but only 0, which is one of the digits that can be used for an octal number (which can use only 8 digits: 0, 1, 2, 3, 4, 5, 6 and 7).

For the same reason the following statement is valid:

long maxLong = 0x7fff_ffff_ffff_ffffL;

In this case, in fact, f is not to be intended as a character, but is actually one of the possible digits of a hexadecimal number (which can use 16 digits: 0, 1, 2, 3, 4, 5, 6 and 7, 8, 9, a, b, c, d, e, f). In hexadecimal notation f is equal to 15.

 

Conclusion

In this article we have explored the use cases in which we can use underscore in Java programming. In particular we have seen that, in addition to the convention that requires its use in the declaration of constant identifiers, from Java 7 onwards it is possible to use underscore as a separator of digits (both integers and decimals), to make them easier to interpret . This practice is more useful when the values to be defined are higher, and it is easy to use since there is only one rule to respect. We have also seen that from Java 9 onwards we can no longer use a single underscore as the identifier of a Java programming element.

 

Note dell’autore

This article is based on a few paragraphs from chapter 3 of my book “Java for Aliens“.

Leave a Reply