EMZETT.
Login

Non-primitive Types (Reference Types)

In short: Data types that don’t directly store a value, but a reference (pointer) to an object in memory — unlike primitive types like byte or double, which contain their value directly.

In more detail: Because a variable of a reference type only stores a reference, several variables can point to the same underlying object — a change via one variable then also affects the other, which doesn’t happen for primitive types (each variable has its own, independent copy). Classic examples of reference types are objects, arrays, and strings.

In Depth

The difference between primitive and reference types shows up most clearly in memory behaviour:

int a = 5;
int b = a;      // b gets an INDEPENDENT copy of 5
b = 10;
System.out.println(a);   // still 5
 
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;        // arr2 points to the SAME array as arr1
arr2[0] = 99;
System.out.println(arr1[0]);   // prints 99 - the same array!

This distinction also affects how values are passed to functions (see Parameters): a primitive value is copied when passed, a reference type only passes the reference — changes to it within the function remain visible to the caller even after it ends.

A special value for reference types is null (or the equivalent in other languages) — it means “this variable currently points to NO object”. Primitive types normally don’t know this state (an int variable always has a concrete numeric value, never “no value”). Attempting to access a field or method of a null reference type leads to one of the most common runtime errors of all (known in Java as a NullPointerException) — modern languages increasingly address this with built-in “optional”/“nullable” concepts that force the compiler to explicitly handle the null case, instead of it being possible to overlook.

Another practical difference: reference types are managed by the garbage collector in languages with automatic memory management — an object stays in memory as long as any reference to it exists, and is only removed once no variable points to it anymore. Primitive values, by contrast, usually sit directly and briefly on the call stack and don’t need this management.

See also: Objects, byte, double