How do you write integer literals in hexadecimal, octal, and binary, and what common bug does the octal form cause?
answer
- 0x = hex, 0b = binary, leading 0 = octal
- Octal has no letter, only a leading zero
- 010 == 8, not 10
- 08 / 09 won't compile (invalid octal digits)
- Never zero-pad decimal literals; use underscores
basics
~10 sHex uses prefix 0x (0x1F), binary uses 0b (0b1010), octal uses a leading zero (017). The trap: a leading zero makes the number octal, so 010 is 8, not 10.
solid answer
~40 sJava integer literals can be written in four bases. Decimal is the default (255). Hexadecimal uses the 0x or 0X prefix with digits 0-9 and a-f (0xFF is 255). Binary, added in Java 7, uses 0b or 0B (0b11111111 is 255). Octal uses a leading 0 with digits 0-7 (0377 is 255). The classic bug is octal: any integer literal that starts with 0 and has more digits is interpreted in base 8, so 010 equals 8 and 0123 equals 83. This silently bites code that zero-pads numbers for alignment, such as 011 meant as eleven, or parses things like 08 which won't even compile because 8 is not a valid octal digit. Best practice: never zero-pad a decimal integer literal; use underscores for grouping instead.
code
java · 10 lines// All four print the SAME value (255) — just different spellings:
System.out.println(255); // decimal -> 255
System.out.println(0xFF); // hex -> 255
System.out.println(0b1111_1111); // binary -> 255
System.out.println(0377); // octal -> 255
// The octal trap:
int padded = 010; // looks like 10, actually 8 (octal)
System.out.println(padded); // -> 8
// int bad = 09; // does NOT compile: 9 is not an octal digitgo deeper
Know the three prefixes (0x, 0b, leading 0) and that 010 is octal 8, not ten.
Explain all four bases, when binary/underscores arrived (Java 7), and articulate the octal-leading-zero bug and how to avoid it.
Discuss why the octal syntax exists (C inheritance), why it is a wart, and how coding conventions/linters guard against accidental octal literals.
Frame it as a language-design backward-compatibility trade-off; advise team conventions, static-analysis rules, and the readability case for hex/binary with underscores over magic decimals.
## Number bases, quickly A **base** (or **radix**) is how many distinct digit symbols a number system uses and what each position is worth. Decimal (base 10) uses digits 0-9; the number `255` means 2x100 + 5x10 + 5x1. Other bases are convenient for low-level work: - **Hexadecimal** (base 16) uses 0-9 then a-f for 10-15; one hex digit equals exactly four bits, so it is compact for bit patterns. - **Binary** (base 2) uses only 0 and 1; it shows the raw bits. - **Octal** (base 8) uses 0-7; one octal digit equals three bits (a relic from older machines, still used in Unix file permissions). ## How Java writes each base Java signals the base with a prefix: | Base | Prefix | Example | Decimal value | |------|--------|---------|---------------| | Decimal | (none) | `255` | 255 | | Hex | `0x` / `0X` | `0xFF` | 255 | | Binary | `0b` / `0B` | `0b1111_1111` | 255 | | Octal | leading `0` | `0377` | 255 | Binary literals were added in **Java 7** (so were underscore digit separators). Hex and octal have existed since Java 1.0. All of these are just *different spellings of the same int/long value* — the type and stored bits are identical; only the source text differs. ## The octal trap in detail Unlike hex (`0x`) and binary (`0b`), octal has **no letter** in its prefix — it is signalled only by a **leading zero**. This means the moment you write an integer literal that starts with `0` and has more than one digit, Java reads it as octal: ```java int a = 010; // NOT 10 — this is octal, value 8 int b = 0123; // NOT 123 — octal, value 83 int c = 08; // COMPILE ERROR — 8 is not a valid octal digit ``` This silently corrupts code in real situations: - **Zero-padding for visual alignment**: a developer lines up numbers as `001, 010, 011` thinking they are 1, 10, 11 — they are actually 1, 8, 9. - **Copying values with leading zeros** (zip codes, time fields, ID prefixes) directly into integer literals. - A literal like `08` or `09` won't compile (the digits 8 and 9 don't exist in octal), which at least surfaces the mistake; but `010` compiles and is wrong, which is worse. ## How to avoid it - **Never zero-pad a decimal integer literal.** Drop the leading zero, or store it as a String if leading zeros are semantically meaningful. - Use **underscores** as digit separators for readability instead: `1_000_000`, `0b1010_0101`. - Use octal *deliberately* only where base-8 is the natural unit (Unix permission masks), and comment it. ## Why it exists at all The leading-zero octal syntax was inherited from the C language for historical compatibility. It is widely regarded as a wart, but removing it would break existing code, so it remains. Knowing it prevents a class of silent, hard-to-spot bugs.
- Why does 08 fail to compile but 010 compiles to a surprising value?A leading zero makes the literal octal (base 8), whose valid digits are 0-7. 08 contains the digit 8, which is invalid in octal, so it is a compile error. 010 contains only valid octal digits, so it compiles — to 1x8 + 0 = 8 — silently differing from the intended 10.
- When is octal actually useful?Mainly for Unix-style file permission masks (e.g. 0644, 0755), where each octal digit maps cleanly to a 3-bit rwx permission group. Outside such bit-grouped domains it is best avoided.
saying these in an interview costs you the question
- Believing a leading zero is harmless padding
- Saying 010 equals 10
- Thinking 08 just works (it fails to compile)
- Confusing the binary 0b prefix with hex 0x