Firdavs Shodiev

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

int age = 25;
age
25
Value stored directly
double pi = 3.14;
pi
3.14
Value stored directly

Reference Storage

String name = "Java";
name
@2a3b
Memory address
Object at @2a3b:
"Java"
int[] nums = {1,2,3};
nums
@5f7c
Memory address
Array at @5f7c:
[1, 2, 3]

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.

← Back to Blog