Skip to main content

Week 1 Day 2 — Primitives, Wrappers, and Boxing

Goal

Today I want a clean split between values and objects.

Main questions:

  1. What are Java’s primitive types?
  2. What is a wrapper type?
  3. What is boxing and unboxing?
  4. Why can == lie with wrappers?
  5. What is null, and which types can be null?

1. Primitive types

Java has eight primitives. They are not objects. They have no methods. They cannot be null.

PrimitiveSize (typical)Default field value
byte8-bit0
short16-bit0
int32-bit0
long64-bit0L
float32-bit IEEE0.0f
double64-bit IEEE0.0d
char16-bit UTF-16 code unit'\u0000'
booleanJVM-dependentfalse

Local primitives have no default. I must assign them before I read them, or the compiler rejects the code.

String is not a primitive. It is a reference type.

Memory sentence:

Primitives are values. They are not objects and they are never null.


2. Wrapper types

Each primitive has a corresponding class in java.lang:

Byte, Short, Integer, Long, Float, Double, Character, Boolean.

Wrappers are objects on the heap. They can be null. They are required wherever Java needs a reference: List<Integer>, JPA entity fields that must distinguish “missing” from 0, and many APIs.

int count = 3; // value
Integer boxed = Integer.valueOf(3); // object on the heap

Use primitives for arithmetic and local counters. Use wrappers when I need null or a generic type argument.


3. Boxing and unboxing

Boxing wraps a primitive in a wrapper object. Unboxing extracts the primitive.

Integer boxed = 3; // autoboxing: Integer.valueOf(3)
int n = boxed; // unboxing: boxed.intValue()

The compiler inserts those calls. They are not free: boxing allocates (or reuses a cached instance), unboxing can throw.

Integer boxed = null;
int n = boxed; // NullPointerException

That NPE is an interview classic. A wrapper field or a Map value can be null. Unboxing it blows up.

Memory sentence:

Autoboxing hides valueOf / intValue. Unboxing a null wrapper is an NPE.


4. The Integer cache and ==

== on wrappers compares references, not numeric value.

Integer a = 127;
Integer b = 127;
a == b; // true: cached

Integer c = 128;
Integer d = 128;
c == d; // false on a typical JVM: different objects
c.equals(d); // true: same numeric value

Integer.valueOf caches −128..127 by spec. Other values may be new objects. Never use == to compare wrapper values.

The same trap exists for interned Strings vs new String("x"). Value comparison is equals. Identity comparison is ==.


5. Arrays are objects

int[] scores = new int[3];

scores is a reference. The array lives on the heap. The three int elements live inside that heap object and default to 0.

scores itself can be null. scores[0] cannot be null because it is a primitive element. Integer[] elements can be null.


6. Spring / JPA connection

  • JSON and JPA often use wrappers so a missing field is null instead of 0.
  • int on an entity cannot represent “not loaded / not set.” Integer can.
  • A boolean primitive defaults to false, which can silently look like a real business value.
  • Prefer int for local math. Prefer Integer on DTOs and entities when absence is data.

7. Common traps

Trap 1: String is a primitive.
It is a reference type. It is immutable. It can be null.

Trap 2: == for Integer.
Works by accident inside the cache range. Fails outside it.

Trap 3: Unboxing null.
Looks like arithmetic. Throws NullPointerException.

Trap 4: Default 0 / false on primitives as “real” domain values.
A primitive cannot say “unknown.”


Practice Questions and Answers

Question 1

Why is String not a primitive?

Answer:

String is a class. Variables of type String are references. The character data lives in a heap object. The variable can be null, and I can call methods on a non-null String. None of that is true of int.


Question 2

What does this print, and why can it surprise people?

Integer a = 128;
Integer b = 128;
System.out.println(a == b);
System.out.println(a.equals(b));

Answer:

a.equals(b) is true. a == b is typically false because 128 is outside the Integer cache, so valueOf returns two objects. Interviewers want equals for values and == only for identity.


Question 3

Why does this throw?

Integer qty = null;
int n = qty + 1;

Answer:

qty + 1 unboxes qty to int. Unboxing null throws NullPointerException.


Question 4

When would I use Integer instead of int on a JPA entity?

Answer:

When null is a meaningful state: “this column is unset.” An int field becomes 0 and I can no longer tell missing from zero.


Question 5

Is int[] a primitive?

Answer:

No. The array is an object on the heap. Its elements are primitives.


Memory sentences

Primitives are values and never null. Wrappers are objects and can be null.

Compare wrapper values with equals, not ==.

Unboxing null is an NPE, not a default 0.

Next: Week 1 Day 3 — Pass-by-value, Identity, and Equality