Java Primitive Data Types

In the last lesson you learned about Java variables, the named boxes that hold a value. But a box needs a label saying what kind of value goes inside. Java gives you eight ready-made labels for simple values: the primitive data types.

πŸ€” The problem: not every number is the same

An age like 25 and a world population like 8000000000 are both whole numbers, but they do not share one type.

  • The age fits in a small box. The population needs a much bigger one.
  • Use a box too small for the value and it overflows into garbage. Java does not warn you.
  • So Java gives a small set of number types, each sized for a different job.

A primitive type is the simplest value Java knows. It holds one single value directly, like one number or one true/false. There are exactly eight.

πŸ“‹ The eight primitives at a glance

Here is the full set in one table. Do not memorise the ranges. Just get a feel for small versus large, and the default value a field gets if you never assign one.

Type Holds Size Range (roughly) Default
byte Whole number 1 byte -128 to 127 0
short Whole number 2 bytes -32,768 to 32,767 0
int Whole number 4 bytes about -2.1 billion to 2.1 billion 0
long Whole number 8 bytes about -9.2 quintillion to 9.2 quintillion 0L
float Decimal number 4 bytes about 7 digits of accuracy 0.0f
double Decimal number 8 bytes about 15 digits of accuracy 0.0
char One character 2 bytes one letter, digit, or symbol blank character
boolean true or false 1 bit (in theory) only true or false false

Bigger types use more bytes. They take more memory but hold bigger or more accurate values. That space-versus-size trade is the whole story of choosing a type.

πŸ”’ Whole number types: byte, short, int, long

These four hold whole numbers, no decimal point. They differ only by how big a number they can hold. Bigger range means more memory used.

Here is each one declared and printed.

byte smallCount = 100;
short mediumCount = 30000;
int age = 25;
long worldPopulation = 8000000000L;
System.out.println(smallCount);
System.out.println(mediumCount);
System.out.println(age);
System.out.println(worldPopulation);

Each line picks the smallest type that fits its value.

  • byte about -128 to 127. For huge amounts of small numbers where you must save memory, like raw image or file data.
  • short up to about 32,000. Rarely used in everyday code.
  • int up to about 2.1 billion either way. Your default for whole numbers.
  • long into the quintillions. Use it when a value might grow past two billion.

Output

100
30000
25
8000000000

In real code you reach for int almost every time. Switch to long only when the number might outgrow int, like a database ID, a population, or milliseconds since 1970.

int vs long: the L suffix

The L on 8000000000L is a literal suffix. A literal is a value you type straight into code, like 8000000000. The suffix tells Java how to read it.

  • L means β€œtreat this number as a long”.
  • Java reads a plain whole number as an int first.
  • A number past about 2.1 billion does not fit an int, so without L the code will not compile.
// ❌ Avoid: Java reads this as an int first, and it is too big to fit
long population = 8000000000;
// βœ… Good: the L tells Java to read it as a long from the start
long population = 8000000000L;
System.out.println(population);

The L must come right after the digits, with no space. Always use capital L. Lowercase l looks too much like the digit 1.

Output

8000000000

πŸ’§ Decimal number types: float and double

For a decimal point, like a price or a measurement, you use one of these two. Again the difference is size versus accuracy.

double price = 19.99;
float rating = 4.5f;
System.out.println(price);
System.out.println(rating);
  • double about 15 digits of accuracy, 8 bytes. The default choice for decimals. The name means β€œdouble precision”, twice the accuracy of a float.
  • float about 7 digits, 4 bytes. Only for special cases where memory or speed matters a lot, like graphics or large scientific data.

Output

19.99
4.5

float vs double: the f suffix and precision

The f on 4.5f is a literal suffix, just like L.

  • f tells Java β€œtreat this as a float”.
  • Without it, Java reads 4.5 as a double by default.
  • A double does not fit a smaller float box on its own, so the code will not compile.
// ❌ Avoid: 4.5 is a double by default, and it does not fit a float on its own
float rating = 4.5;
// βœ… Good: the f marks it as a float
float rating = 4.5f;
System.out.println(rating);

Output

4.5

For everyday code, just use double. It is more accurate and you skip the suffix. But know this about decimals: a double is not perfectly exact. A number like 0.1 cannot be stored exactly in binary, so tiny rounding gaps show up.

double total = 0.1 + 0.2;
System.out.println(total);

Output

0.30000000000000004

That tiny extra is the rounding gap. It is fine for most maths. But for money, where every cent must be exact, programs use whole int cents or a special type instead of double.

πŸ”€ The single character type: char

The char type holds one single character: one letter, digit, or symbol. You write the value in single quotes.

char grade = 'A';
char firstInitial = 'R';
char dollarSign = '$';
System.out.println(grade);
System.out.println(firstInitial);
System.out.println(dollarSign);

Note the quotes:

  • Single quotes mean one char.
  • Double quotes like "A" mean a String, a different type entirely.
  • Mixing them up is a common slip. We will see it again in the mistakes section.

Output

A
R
$

Here is a neat detail: a char is stored as a number underneath.

  • Each character has a code number from Unicode, the worldwide standard for character codes.
  • So 'A' is 65, 'B' is 66, and so on.
  • That is why a char takes 2 bytes, enough room for letters from many languages.
  • Because it is really a number, you can do maths with it.
char letter = 'A';
int code = letter; // read the char as its number
System.out.println(code);
System.out.println((char) (letter + 1)); // the next character

Output

65
B

βœ… The true or false type: boolean

Often you just need a yes-or-no answer: is the game over, is the user logged in, did the payment succeed. For that, Java has boolean. It holds only true or false. Not 1, not "yes", just those two.

boolean isGameOver = false;
boolean hasPassed = true;
System.out.println(isGameOver);
System.out.println(hasPassed);

Output

false
true

A boolean is the backbone of decisions. Your if statements and loops will all rely on booleans to choose what to do. Notice the names read like a question: isGameOver, hasPassed. That is a good habit, so the code says what it means.

πŸ› οΈ A worked example with output

Let’s put several types together for one student record. We pick a type for each piece of data based on what the real value looks like.

public class StudentRecord {
public static void main(String[] args) {
int age = 20; // a whole number, so int
char grade = 'A'; // one character, so char
double gpa = 3.85; // a decimal, so double
long studentId = 100200300400L; // big number, so long with L
boolean isEnrolled = true; // a yes/no value, so boolean
System.out.println("Age: " + age);
System.out.println("Grade: " + grade);
System.out.println("GPA: " + gpa);
System.out.println("ID: " + studentId);
System.out.println("Enrolled: " + isEnrolled);
}
}

Each choice shows the type rule in action.

  • age is a small whole number, so int. No suffix needed.
  • grade is a single character, so char with single quotes.
  • gpa has a decimal point, so double.
  • studentId is past two billion, so long with the L suffix.
  • isEnrolled is a yes-or-no fact, so boolean.

Each + joins the label text and the value into one piece of text to show on screen.

Output

Age: 20
Grade: A
GPA: 3.85
ID: 100200300400
Enrolled: true

The type just follows the shape of the real value. That is the whole skill: look at the data, then pick the type that fits.

⚠️ Common Mistakes

These type slip-ups catch people often. Here is each one and its fix.

Overflow: a number outgrows its type. Push past a whole-number type’s top limit and the value wraps around to the bottom, like a clock rolling from 12 back to 1. This is overflow. Java does not warn you. The result is silently wrong.

// ❌ Avoid: int max is about 2.1 billion, this wraps around to a negative number
int big = 2147483647;
big = big + 1;
System.out.println(big); // prints -2147483648, not what you expect
// βœ… Good: use long when a value can grow large
long big = 2147483647L;
big = big + 1;
System.out.println(big); // prints 2147483648 correctly

Output

-2147483648
2147483648

Int division: whole-number maths drops the decimal. Divide two int values and Java throws away the remainder. So 7 / 2 is 3, not 3.5. The fix: make at least one side a decimal type.

// ❌ Avoid: both sides are int, so the decimal is lost
int wrong = 7 / 2;
System.out.println(wrong); // prints 3, not 3.5
// βœ… Good: use a decimal so the fraction is kept
double right = 7.0 / 2;
System.out.println(right); // prints 3.5

Output

3
3.5

Wrong or missing literal suffix. A whole number bigger than two billion needs the L to be a long. A float value needs the f. Forget the suffix and the code will not compile.

// ❌ Avoid: too big for int, and no L suffix
long population = 8000000000;
// βœ… Good: the L marks it as a long
long population = 8000000000L;

Putting a decimal in an int. An int holds whole numbers only. Java will not quietly round, so the line below fails to compile. Use double for the decimal.

// ❌ Avoid: an int cannot hold a decimal
int price = 19.99;
// βœ… Good: double holds the decimal
double price = 19.99;

Using single quotes for text. Text needs double quotes. Single quotes are only for one char.

// ❌ Avoid: single quotes try to make a char hold a whole word
char name = 'Alex';
// βœ… Good: double quotes for text
String name = "Alex";

βœ… Best Practices

Simple habits make type choices easy.

  • Default to int and double. Reach for the others only with a clear reason.
  • Use long when a count can grow large. IDs, populations, and milliseconds all overflow an int. Remember the L.
  • Use boolean for yes/no values. Name it like a question, such as isReady or hasPaid.
  • Pick double over float. More accurate, no f suffix. Choose float only when memory or speed is a proven concern.
  • Match the type to the real data. Age is int, price is double, a grade letter is char, a yes/no fact is boolean.
  • Watch for overflow and int division. If a result looks very wrong, check for an overflow or a lost decimal from two int values.

🧩 What You’ve Learned

Nice work. Here is what to lock in.

  • βœ… Java has exactly eight primitive types, each holding one simple value directly.
  • βœ… Whole numbers use byte, short, int, long. int is the everyday choice; long needs the L suffix for big values.
  • βœ… Decimals use double (the default) and float (4.5f needs the f), and decimals can carry tiny rounding gaps.
  • βœ… char holds one character in single quotes, stored as a Unicode number underneath.
  • βœ… boolean holds only true or false, and powers decisions.
  • βœ… Each type has a size, a range, and a default value, and picking the right one avoids overflow and lost decimals.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    Which type is the everyday choice for whole numbers?

    Why: int is the standard choice for whole numbers in most Java code. You only switch to long when the value might pass two billion.

  2. 2

    Why does a long literal like 8000000000 need the L suffix?

    Why: Java reads a plain whole number as an int first. A value past about 2.1 billion does not fit in an int, so the L tells Java to treat it as a long.

  3. 3

    What does 7 / 2 print when both values are int?

    Why: Dividing two int values does whole-number division and drops the remainder, so 7 / 2 is 3. Use 7.0 / 2 to keep the 3.5.

  4. 4

    Which type would you use for a true-or-false value like isLoggedIn?

    Why: A boolean holds only true or false, which is exactly what a yes/no value needs.

πŸš€ What’s Next?

You now know the eight simple types that hold one value each. Java also has bigger types for text, collections, and objects you build yourself. Those are the non-primitive types, and they work a little differently. That is up next.

Java Non-Primitive Data Types

Share & Connect