Primitives are Apex’s single-value types — the atomic building blocks that everything else (collections, sObjects, custom classes) is composed of. Apex defines 11 primitives, each tuned for a specific kind of value. They’re passed by value in method calls, which is one of the most-asked subtleties in Apex interviews.
The 11 primitives
| Type | Stores | Default | Example |
|---|---|---|---|
Boolean | true or false | null | Boolean isActive = true; |
Integer | 32-bit signed integer (−2,147,483,648 to 2,147,483,647) | null | Integer count = 42; |
Long | 64-bit signed integer | null | Long ts = 1_700_000_000_000L; |
Decimal | Arbitrary-precision decimal — best for money | null | Decimal price = 19.95; |
Double | 64-bit IEEE 754 floating-point | null | Double pi = 3.14159; |
String | UTF-16 text up to 6 million characters | null | String name = 'Acme'; |
Date | Calendar date (year/month/day, no time) | null | Date today = Date.today(); |
Time | Time of day (hour/minute/second/ms) | null | Time t = Time.newInstance(9, 0, 0, 0); |
Datetime | Date + time in UTC | null | Datetime now = Datetime.now(); |
Id | 15- or 18-character Salesforce record Id | null | Id a = '001xx...'; |
Blob | Binary data (images, PDFs, JSON bodies) | null | Blob b = Blob.valueOf('hi'); |
A twelfth type, Object, is technically the root of all types — including primitives — but it’s not a primitive itself.
Decimal vs Double — the interview classic
Use Decimal for any value where rounding matters: currency, percentages, scientific tolerances, anything stored in a Salesforce Currency or Percent field. Decimal is arbitrary precision (up to 50 significant digits) with predictable rounding.
Use Double for: scientific calculations where speed matters more than the 16th decimal digit. Salesforce’s standard fields almost never map to Double — Currency fields are Decimal underneath.
Decimal total = 0.1 + 0.2; // 0.3 exactly
Double total2 = 0.1d + 0.2d; // 0.30000000000000004 — IEEE 754
Integer vs Long
Integer overflows silently at 2,147,483,647. Anything counting Unix epoch milliseconds, large IDs, or page-view counters needs Long.
Integer i = 2_000_000_000; // OK
Integer j = i + i; // overflows silently to negative
Long k = 2_000_000_000L * 2; // safe
Strings — immutable, comparable, 16-bit
- Immutable:
s.toUpperCase()returns a new String;sis unchanged. - Heap-counted: every character is 2 bytes (UTF-16). A 3 MB String fills half the heap budget.
- Equality:
==compares values, not references.'abc' == 'abc'is true even though they could be separate instances. - Case-insensitive in SOQL:
WHERE Name = 'ACME'matches'Acme'. The Apex==is case-sensitive on String.
Id — a typed String
Id is a String at runtime, but the compiler verifies it’s either 15 or 18 characters and uses a valid Salesforce key prefix.
Id i = '001xx0000000001'; // valid Account 15-char Id
Id j = 'not-an-id'; // compile time? no — runtime System.StringException
Use Id instead of String for record references — you get a clearer signature and runtime validation.
Passed by value (with one caveat)
When you pass a primitive into a method, Apex copies the value. Changes inside the method don’t affect the caller:
public void noChange(Integer n) { n = 99; }
Integer x = 1;
noChange(x);
System.debug(x); // still 1
The caveat: SObjects and collections are also passed by value of the reference. The reference is copied — both caller and callee point to the same object. Mutating the object’s fields from the callee does affect the caller, because it’s the same object. This is true in many languages but trips up Apex newcomers.
Type conversion
Most conversions are explicit:
Integer i = Integer.valueOf('42');
String s = String.valueOf(42);
Decimal d = Decimal.valueOf('19.95');
Date today = Date.today();
Datetime nowTs = Datetime.newInstance(Long.valueOf('1700000000000'));
Implicit widening happens for numeric types: Integer → Long → Decimal/Double is automatic; the reverse requires explicit casting (and may lose data).
What interviewers are really looking for
The naming check is fine. The senior signal is knowing Decimal vs Double for currency and Integer vs Long for big numbers. Mentioning Apex pass-by-value and the SObject reference caveat (“the reference is copied, but it’s still the same object”) proves you understand how parameters work. Calling out Id as a validated String shows you write idiomatic Apex, not Java-with-different-syntax.
Verified against: Apex Developer Guide — Primitive Data Types. Last reviewed 2026-05-17.