2.1 The Eight Primitive Data Types & Literal Values
Key Takeaways
- Java defines exactly eight primitive types: byte, short, int, long, float, double, char, and boolean, storing raw values directly on the stack without object overhead.
- Non-decimal integer literals default to 32-bit int; literals exceeding 2,147,483,647 require an explicit L or l suffix to compile as 64-bit long values.
- Floating-point literals default to 64-bit double; assigning a decimal literal to a 32-bit float requires an explicit F or f suffix to prevent compiler conversion errors.
- char is a 16-bit unsigned Unicode numeric type (0 to 65,535), while boolean represents pure logical truth (true or false) and cannot be cast to or from any numeric type.
- Class and instance member fields automatically receive default initialization values (0, 0.0, false, '\u0000', null), whereas local variables receive no default values and fail compilation if read before definite assignment.
2.1 The Eight Primitive Data Types & Literal Values
Quick Summary: Java partitions all data into primitive types and reference types. The eight primitives (
byte,short,int,long,float,double,char,boolean) store raw binary values directly on the call stack for maximum runtime efficiency. Integer literals default to 32-bitint, floating-point literals default to 64-bitdouble, andcharrepresents 16-bit unsigned Unicode characters. While object and class fields receive automatic default values upon allocation, local variables declared within methods receive no default value and fail compilation if read before explicit initialization.
1. The Primitive vs. Reference Distinction
In Java, every variable declaration binds an identifier to a specific, immutable data type. Java's type system is bifurcated into two distinct categories:
- Primitive Types: Built directly into the core Java language specification. A primitive variable reserves a fixed number of bits in memory and stores its raw binary data value directly in that memory slot (typically on the thread call stack). Primitives have no methods, cannot be invoked with the dot (
.) operator, possess no internal object header overhead, and can never hold the valuenull. - Reference Types: Built upon classes, interfaces, or arrays (such as
java.lang.String,java.util.Scanner, orint[]). A reference variable does not hold object data directly; instead, it stores a memory address (pointer) that refers to an object located on the garbage-collected Java heap.
STACK MEMORY HEAP MEMORY
+-----------------------+ +---------------------------+
| primitive: int age=25 | | |
| (Holds raw value 25) | | |
+-----------------------+ | |
| reference: String name| ---------------> | String Object ("Alice") |
| (Holds heap address) | | (Object header, char[]) |
+-----------------------+ +---------------------------+
Understanding this physical separation is foundational for Exam 1Z0-811: primitive variables represent pure data, whereas reference variables represent handles pointing to objects.
2. Comprehensive Breakdown of the Eight Primitive Types
Java provides exactly eight primitive data types. They are classified into four integer types, two floating-point types, one character type, and one boolean type.
| Type | Classification | Width | Byte Size | Value Range (Inclusive) | Default Field Value | Literal Example |
|---|---|---|---|---|---|---|
byte | Signed Integer | 8 bits | 1 byte | -128 to 127 (-2^7 to 2^7 - 1) | 0 | (byte) 100 |
short | Signed Integer | 16 bits | 2 bytes | -32,768 to 32,767 (-2^15 to 2^15 - 1) | 0 | (short) 5000 |
int | Signed Integer | 32 bits | 4 bytes | -2,147,483,648 to 2,147,483,647 | 0 | 42 |
long | Signed Integer | 64 bits | 8 bytes | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | 0L | 5000000000L |
float | Floating-Point | 32 bits | 4 bytes | IEEE 754 (±1.4E-45 to ±3.4028235E+38) | 0.0f | 3.14159F |
double | Floating-Point | 64 bits | 8 bytes | IEEE 754 (±4.9E-324 to ±1.7976931348623157E+308) | 0.0d | 2.71828 |
char | Unsigned Unicode | 16 bits | 2 bytes | 0 to 65,535 ('\u0000' to '\uffff') | '\u0000' | 'A', '\u0041' |
boolean | Logical Truth | JVM dep. | JVM dep. | true or false | false | true, false |
The Four Signed Integer Types
All integer types in Java are signed, utilizing two's complement binary representation. Java has no unsigned modifier for primitive declarations.
byte(8-bit) andshort(16-bit) are primarily used for low-level stream I/O, binary file structures, or large memory arrays where conserving heap space is paramount.int(32-bit) is the default standard type for all integer computations in Java. Modern CPU architectures are optimized for 32-bit and 64-bit math.long(64-bit) is required when values exceed roughly 2.14 billion, commonly used for high-precision timestamps, financial transaction identifiers, and large counter metrics.
The Two Floating-Point Types
Java conforms strictly to the IEEE 754 standard for binary floating-point arithmetic.
float(32-bit single precision): Provides roughly 6 to 7 decimal digits of precision. Because decimal literals default todouble, assigning a decimal number to afloatwithout anForfsuffix causes a compilation error.double(64-bit double precision): Provides roughly 15 to 17 decimal digits of precision. It is the default type for all floating-point expressions and numeric literals with decimal points in Java.
Exam Watch: Neither
floatnordoubleshould ever be used for exact monetary or financial calculations due to binary floating-point rounding errors (e.g.,0.1 + 0.2does not equal0.3exactly). For precise currency, commercial Java applications usejava.math.BigDecimal.
3. Integral Literals & Alternate Number Systems
A literal is the source code representation of a fixed value. In Java, any whole number written directly into code (such as 10, 0, -500) is automatically assigned the primitive type int by the compiler.
The long Literal Suffix (L / l)
Because whole numbers default to 32-bit int, if you write a numeric literal that exceeds the maximum int value (2,147,483,647), the compiler issues an immediate syntax error unless you explicitly inform it that the literal is a 64-bit long:
// COMPILE ERROR: integer number too large: 3000000000
long distanceToMars = 3000000000;
// CORRECT: Append 'L' to declare a 64-bit long literal
long distanceToMars = 3000000000L;
Always use the uppercase L suffix. While the lowercase l is grammatically legal, it looks virtually indistinguishable from the digit 1 in standard programming fonts (e.g., 50l looks like 501).
Alternate Radix Representations
Java supports integer literals expressed in four distinct numeral systems:
int decimalVal = 26; // Base 10: Standard digits 0-9 (no prefix)
int octalVal = 032; // Base 8: Digits 0-7, preceded by leading zero '0'
int hexVal = 0x1A; // Base 16: Digits 0-9, A-F, preceded by '0x' or '0X'
int binaryVal = 0b11010; // Base 2: Digits 0-1, preceded by '0b' or '0B'
// All four variables evaluate to the exact same numerical quantity: 26
System.out.println(decimalVal == octalVal); // prints true
System.out.println(hexVal == binaryVal); // prints true
Exam Trap: Beware of leading zeros! Writing
int code = 053;does not store decimal 53; it stores octal 5 * 8^1 + 3 * 8^0 = 43. Furthermore, writingint err = 089;triggers a compile error because digits8and9are invalid in base 8.
4. Character & Boolean Primitive Details
The char Primitive: Unsigned 16-Bit Unicode
Unlike languages where a char is an 8-bit ASCII value, Java was designed from the ground up for internationalization. A Java char is a 16-bit unsigned integer representing UTF-16 code units with a numerical range from 0 to 65,535 (0x0000 to 0xFFFF).
- Character literals must be enclosed in single quotes (
'Z'), whereasStringliterals use double quotes ("Z"). - Because
charis fundamentally an unsigned numeric type, you can assign integers or Unicode hexadecimal escapes directly to acharvariable:
char c1 = 'A'; // Standard character literal
char c2 = 65; // Decimal Unicode code point for 'A'
char c3 = '\u0041'; // 4-digit hexadecimal Unicode escape sequence for 'A'
System.out.println(c1 == c2); // prints true
System.out.println(c2 == c3); // prints true
Common character escape sequences:
'\n': Linefeed / newline'\t': Horizontal tab'\'': Single quote character'\"': Double quote character'\\': Backslash character
The boolean Primitive: Isolated Truth Values
A boolean variable holds only one of two literal values: true or false.
CRITICAL EXAM RULE: In Java,
booleanvalues have no numeric equivalence. Unlike C or C++,truedoes NOT equal1, andfalsedoes NOT equal0. You cannot convert, cast, or compare integers and booleans. Statements such asif (1)orboolean flag = (boolean) 0;fail compilation immediately.
5. Underscores in Numeric Literals (Java 7+)
To make large numeric literals readable to human developers, Java permits placing underscore characters (_) between digits.
int oneMillion = 1_000_000; // Much easier to read than 1000000
long creditCardNumber = 4532_8910_1234_5678L;
float piApprox = 3.14_15_92F;
int hexBytes = 0xFF_EC_00_12;
int binaryNibbles = 0b1101_0110_0010_1111;
Strict Restrictions on Underscore Placement (Exam Traps)
The compiler strictly enforces that underscores may only appear between adjacent digits. The following placements are compile-time syntax errors:
- At the start or end of a literal:
int bad1 = _52; // ERROR: parsed as an identifier name, not a literal! int bad2 = 52_; // ERROR: illegal underscore at end of literal - Adjacent to a decimal point:
float bad3 = 3._14F; // ERROR: underscore adjacent to decimal point float bad4 = 3_.14F; // ERROR: underscore adjacent to decimal point - Adjacent to type suffixes (
L,F,D):long bad5 = 999_L; // ERROR: underscore adjacent to 'L' suffix float bad6 = 5.0_F; // ERROR: underscore adjacent to 'F' suffix - Adjacent to radix prefixes (
0x,0b):int bad7 = 0_x52; // ERROR: underscore inside radix prefix int bad8 = 0x_52; // ERROR: underscore immediately following radix prefix int bad9 = 0b_1010; // ERROR: underscore immediately following radix prefix
6. Field Default Values vs. Uninitialized Local Variables
A critical objective on Exam 1Z0-811 is understanding where default values are assigned and where they are omitted.
+------------------------------------+-------------------------------------+
| Class & Instance Fields | Local Variables |
+------------------------------------+-------------------------------------+
| Declared inside class body | Declared inside a method, loop, |
| (static fields or instance fields) | constructor, or block parameter |
| Allocated on the Heap | Allocated on the Stack Frame |
| Automatically given DEFAULT values | NEVER given default values |
| Safe to read without assignment | COMPILE ERROR if read uninitialized |
+------------------------------------+-------------------------------------+
Automatic Default Values for Fields
When an object is instantiated or a class is loaded, the JVM automatically initializes all member fields to predefined defaults:
byte,short,int,long->0float,double->0.0f/0.0dchar->'\u0000'(the null character, integer value 0)boolean->false- All reference types (
String, arrays, custom objects) ->null
The Definite Assignment Rule for Local Variables
Local variables live on stack frames. Allocating and zeroing stack memory for every method call would impose substantial performance degradation. Consequently, Java does not initialize local variables.
A local variable can be declared without an initial value, but the compiler enforces definite assignment: if there is any theoretical path through your code where a local variable might be read before receiving an explicit value, compilation fails:
public class InitializationDemo {
int instanceCounter; // Field: automatically initialized to 0
boolean isReady; // Field: automatically initialized to false
public void compute() {
int localTotal; // Local variable: uninitialized
System.out.println(instanceCounter); // COMPILES: prints 0
System.out.println(isReady); // COMPILES: prints false
// System.out.println(localTotal); // COMPILE ERROR: variable localTotal might not have been initialized
}
}
Even if an assignment occurs inside a conditional statement, the compiler flags an error if the condition cannot be proven true at compile time:
public void conditionalInit(boolean condition) {
int x;
if (condition) {
x = 100;
}
// If condition is false, x was never assigned!
// System.out.println(x); // COMPILE ERROR: variable x might not have been initialized
}
Which of the following numeric literal declarations compiles successfully without errors?
Consider the following Java class definition:
What occurs when an attempt is made to compile this code?public class TestScope {
int score;
boolean active;
public void evaluate() {
int count;
if (score == 0) {
count = 10;
}
System.out.println(score);
System.out.println(active);
System.out.println(count);
}
}
Which statement accurately describes the characteristics and behavioral constraints of Java primitive types?