Java Variables: Primitives and References
Published on February 8, 2026
In Java, variables are divided into primitive types and reference types. Primitive types include basic data types like int, double, char, and boolean, which store values directly. Reference types, such as String and arrays, store references to objects in memory. This fundamental difference impacts how data is handled, passed between methods, and managed in Java applications.
Primitive Types
Primitive types are the basic building blocks. They're not objects — they're just raw data stored directly in memory. Java has eight of them: byte, short, int, long, float, double, char, and boolean. Each one has a specific size in bytes and can hold certain values.
| Type | Bytes | Value Range |
|---|---|---|
| byte | 1 | [-128, 127] |
| short | 2 | [-32,768, 32,767] |
| int | 4 | [-2.147B, 2.147B] |
| long | 8 | ≈[-9.22E18, 9.22E18] |
| float | 4 | Approximately ±3.4028235E+38F (6-7 significant decimal digits) |
| double | 8 | Approximately ±1.7976931348623157E+308 (15 significant decimal digits) |
| char | 2 | [0, 65,535] (Unicode characters) |
| boolean | 1 (varies) | true or false |
Let's see some examples. Declaring a primitive is straightforward:
int age = 25; double pi = 3.14159; char letter = 'A'; boolean isJavaFun = true;
Key Differences Among Primitives
Different numeric types exist to balance range, precision, and memory usage.
For decimal numbers, double is the safe default because it provides about 15 significant digits of precision. float uses half the memory but only around 6–7 significant digits, so prefer float only when memory is constrained.
For whole numbers, int (4 bytes) covers most everyday needs (≈[-2.147B, 2.147B]). Choose long (8 bytes) when you need much larger ranges, such as for timestamps or very large counters. Long literals should be suffixed with L, for example long bigNum = 1234567890123L;.
byte (1 byte) and short (2 bytes) are useful for memory-sensitive or low-level data. Use byte for raw binary values and short for compact 16-bit numbers; int remains the practical default for most integer work.
char stores a single Unicode code unit (0–65,535) and can participate in arithmetic, for example char next = 'A' + 1;.
boolean represents true or false and is used in conditions and control flow.
Reference Types
Now, reference types are different. These point to objects in memory. When you create a reference variable, you're really just holding a reference (like an address) to the actual object. Strings, arrays, and any class you define are reference types.
How Memory Works: Primitives vs References
Understanding how Java stores primitives versus references in memory helps clarify their fundamental difference. When you declare a primitive, the variable directly contains the value. When you declare a reference, the variable contains a memory address pointing to where the actual object lives.
Primitive Storage
Reference Storage
This distinction explains why copying primitives creates independent values, while copying references creates two variables pointing to the same object. Modifying the object through one reference affects what you see through the other reference.
| Type | Description | Example |
|---|---|---|
| String | Immutable sequence of characters | String greeting = "Hello World"; |
| Array | Fixed-size collection of elements of the same type | int[] nums = new int[5]; |
| Object | Base class for all classes | Object obj = new Object(); |
| Class instances | Objects created from user-defined classes | MyClass mc = new MyClass(); |
For example:
String name = "Firdavs";
int[] numbers = {1, 2, 3, 4, 5};
Here, 'name' doesn't hold the string "Firdavs" directly; it holds a reference to where that string is stored. Same with the array.
One key difference: primitives are passed by value, meaning when you assign one to another, it copies the value. Reference variables are also passed by value, but the value being copied is the memory address, not the object itself. This means multiple variables can point to the same object.