The following code :
int i = 0_10;
System.out.println(i);
produces the output:
8
In the javadocs, it is written that we cannot put underscores
at the beginning of a number as in the example int x5 = 0x_52;
, which produces the error illegal underscore
.
However, in this code, 0
is the prefix for octal numbers, as we can see that the output is 8
. But the error is not produced.
i
is 8, which means that 0_10
is an octal number, and 0
is the prefix.0_10
does not produce the illegal underscore error, which implies that 0
is not the prefix, but a part of the number.Why does it not produce the error? Does java treat it partially as octal, and partially not?
Because the JLS says:
Underscores are allowed as separators between digits that denote the integer.
(My emphasis) The underscore in 0x_52
is not between digits.
Yes, it's a bit odd that the indicator that a number is in octal is just that it starts with a 0
(not followed by an x
). And it's caused No End Of Confusion, but it (the 0
) is a digit, and so 0_10
fits the JLS rules.
It does go on to be explicit about it:
In a hexadecimal or binary literal, the integer is only denoted by the digits after the 0x or 0b characters and before any type suffix. Therefore, underscores may not appear immediately after 0x or 0b, or after the last digit in the numeral.
In a decimal or octal literal, the integer is denoted by all the digits in the literal before any type suffix.
Note the distinction. (For clarity: By "type suffix" they're talking about the l
/L
for "long", f
/F
for "float", etc.)
Does java treat it partially as octal, and partially not?
It doesn't. The 0
is part of the number, and also an indicator the number is in octal. It's a bizarre notational idea from C in the 1970s that got inherited by Java when Gosling was designing it to use a syntax similar to C's in the 1990s.
It's worth noting that this bizarre notation has caused enough trouble that when they finally officially added octal to JavaScript (a different language also using a similar syntax), they used 0o
as the prefix instead. (Prior to the 2015 spec, there was no official octal form in JavaScript, although note was made in the 2009 spec that some implementations had done the C thing. As of the 2009 spec they aren't allowed to in strict mode, and the 2015 spec introduced 0o
. [In the 2015 spec, they also made the old "legacy" form required in browsers [only] in loose mode, for compatibility reasons.])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With