Data Types Deep Dive
All eight primitives, memory, and the type system
Quick check before you start: Can you declare variables of the four core types? Do you know when to use
intvsdouble?Practice this topic: Lab 1 exercises on type selection
After this lesson, you will be able to:
- Name all eight primitive types and explain when to use each
- Describe the memory trade-offs between integer types
- Explain what integer overflow is and why it happens
- Distinguish between primitive types and reference types
- Choose the correct type for real-world data
Why Eight Types?
In the previous lesson you learned the four types that cover 99% of CS1: int, double, boolean, and char. But Java has eight primitive types. Why?
Different data has different needs. A person’s age (0-120) does not require the same memory as the number of atoms in the universe. A price needs decimal precision; a student ID does not.
By choosing the right type, you communicate your intent to other programmers, optimize memory, and prevent overflow errors.
From CSCD 110: Python had essentially two numeric types:
int(unlimited size) andfloat. Java exposes the details: four integer types, two decimal types. This is part of Java’s explicit philosophy — you control everything, and the compiler verifies your choices.
The Complete Primitive Type Menu
Integer Types: Four Sizes
All four store whole numbers, differing only in size and range:
| Type | Size | Range | When to Use |
|---|---|---|---|
byte |
1 byte | -128 to 127 | Rare in CS1. Tiny data like file bytes. |
short |
2 bytes | -32,768 to 32,767 | Rare in CS1. Compact integers. |
int |
4 bytes | ±2.1 billion | Default choice. |
long |
8 bytes | ±9.2 quintillion | Very large numbers. |
public class Types {
public static void main(String[] args) {
byte smallCount = 100;
short mediumCount = 30000;
int studentCount = 150;
long worldPopulation = 8_000_000_000L; // L suffix required!
}
}
Notice the L suffix on long literals. Without it, Java treats the number as an int, and 8 billion overflows.
Key insight: Default to
int. Uselongonly when values exceed ±2.1 billion (timestamps, file sizes, population counts).
Floating-Point Types: Two Levels of Precision
| Type | Size | Precision | When to Use |
|---|---|---|---|
float |
4 bytes | ~7 digits | Rare. Graphics, memory-constrained. |
double |
8 bytes | ~15 digits | Default choice. |
public class Floats {
public static void main(String[] args) {
float approximatePi = 3.14159f; // f suffix required
double precisePi = 3.141592653589793;
}
}
A float literal requires the f suffix. Without it, Java treats it as a double.
Key insight: Default to
double. The name means “double-precision.” You will not needfloatin this course.
Boolean and Char (Review)
| Type | Size | Description |
|---|---|---|
boolean |
1 bit* | Only true or false. Not an integer. |
char |
2 bytes | One Unicode character in single quotes: 'A' |
All Eight at a Glance
Integer Types: byte → short → int → long
(1B) (2B) (4B) (8B)
Floating-Point: float → double
(4B) (8B)
Other: boolean char
Shaded/italic types are your everyday choices in CS1.
Numeric Literal Suffixes
Java needs to know the type of every literal:
- Whole numbers (like
42) areintby default - Decimals (like
3.14) aredoubleby default
| Suffix | Type | Example |
|---|---|---|
L |
long |
8_000_000_000L |
f |
float |
3.14f |
| (none) | int / double |
42, 3.14 |
You can use underscores for readability — the compiler ignores them:
int population = 8_000_000; // easier to read than 8000000
long bigNumber = 9_223_372_036_854L;
Watch out: Always use uppercase
L. The lowercasellooks like the digit1in many fonts.
int. If the value exceeds int's range (±2.1 billion), you need the L suffix to make it a long literal.
Integer Overflow: When Numbers Wrap Around
What happens when you exceed the maximum value of a type?
public class Overflow {
public static void main(String[] args) {
int maxInt = Integer.MAX_VALUE; // 2,147,483,647
System.out.println("Max int: " + maxInt);
System.out.println("Max int + 1: " + (maxInt + 1));
}
}
Output:
Max int: 2147483647
Max int + 1: -2147483648
Adding 1 to the maximum int does not cause an error. The value silently wraps around to the most negative int. This is integer overflow — one of the most insidious bugs because it happens silently. No crash, no error message, just a wrong answer.
The trick: Think of an odometer. When it hits 999,999, the next mile rolls to 000,000. Java’s
intworks the same way. The fix? Use a larger type.
long bigValue = (long) Integer.MAX_VALUE + 1;
System.out.println(bigValue); // prints 2147483648 (correct!)
Floating-Point Precision: Not Quite Perfect
Floating-point numbers have a different limitation: precision. They cannot represent every decimal exactly.
public class Precision {
public static void main(String[] args) {
double result = 0.1 + 0.2;
System.out.println(result); // prints: 0.30000000000000004
}
}
Wait — $0.1 + 0.2$ is not exactly $0.3$? Correct. This is not a Java bug. It is a fundamental limitation of binary floating-point representation. The number $0.1$ cannot be represented exactly in binary, just as $\frac{1}{3}$ cannot be represented exactly in decimal.
For CS1, this tiny error is usually insignificant. But be aware:
Watch out: Never compare floating-point numbers with
==. Because of precision errors,0.1 + 0.2 == 0.3evaluates tofalse.
Primitive Types vs. Reference Types
Java has two fundamentally different categories:
Primitive types store the value directly in the variable:
int age = 25; // age contains the actual number 25
Reference types store a reference (a pointer) to data stored elsewhere:
String name = "Alice"; // name contains a reference to the String object
| Category | Types | Naming | Storage |
|---|---|---|---|
| Primitives | 8 types: byte, short, int, long, float, double, boolean, char | Lowercase | Value directly |
| References | String, Scanner, arrays, every class | Uppercase (PascalCase) | Reference to object |
Key insight: Lowercase first letter = primitive. Uppercase = reference. This naming convention tells you instantly what category you are looking at. We will explore what “reference” really means in Week 9 when we study objects.
Default Values: Fields vs. Local Variables
Local variables (inside a method) have no default value. You must initialize them:
public class LocalVar {
public static void main(String[] args) {
int count;
System.out.println(count); // COMPILER ERROR: not initialized
}
}
Fields (inside a class, outside any method) receive default values:
class Student {
int age; // default: 0
double gpa; // default: 0.0
boolean enrolled; // default: false
char grade; // default: '\u0000' (null character)
String name; // default: null (no object)
}
For the next several weeks, every variable you write is a local variable. Initialize everything when you declare it.
Choosing the Right Type
Here is a decision guide for real-world data:
| Data | Type | Why |
|---|---|---|
| Student’s age | int |
Whole number |
| Room temperature | double |
Has decimals |
| Passed exam? | boolean |
Yes/no |
| Letter grade | char |
Single character |
| Zip code | String |
Leading zeros matter! |
| Annual salary | double |
Money has decimals |
| World population | long |
Exceeds 2.1 billion |
| Phone number | String |
Dashes, parentheses |
| Number of credits | int |
Small whole number |
| Checkbox checked? | boolean |
On/off |
The trick: If you would never do arithmetic on it (you would never add two zip codes), it is a
String, not a number.
What you learned
- Java has eight primitive types. Four integers (
byte,short,int,long), two decimals (float,double), plusbooleanandchar. - Default to
intanddouble. Use the others only when you have a specific reason. - Literal suffixes matter.
Lfor long,ffor float. Underscores improve readability. - Integer overflow wraps silently. Every type has a maximum. Choose a type large enough for your data.
- Floating-point precision is limited. Never compare doubles with
==. - Primitives store values; references store addresses. Lowercase = primitive. Uppercase = reference.
- Local variables must be initialized. No default value.
What Comes Next
Next: Scanner, integer division, % (modulus), and the nextInt()/nextLine() buffer trap.
Related Resources
- Reges & Stepp, Chapter 2 — Additional reading on data types