The 8 Primitive Types
Java Primitive Data Types
Java has exactly 8 primitive types. They are not objects and are stored directly in memory.
Numeric Types
// Integer types (whole numbers)
byte temperature = -128; // 8 bits, range: -128 to 127
short population = 32000; // 16 bits, range: -32,768 to 32,767
int salary = 150000; // 32 bits, range: -2^31 to 2^31-1
long worldPopulation = 8000000000L; // 64 bits, range: -2^63 to 2^63-1
// Floating-point types (decimal numbers)
float pi = 3.14159f; // 32 bits, ~7 decimal digits precision
double precise = 3.141592653589793; // 64 bits, ~15 decimal digits precision
// Other types
char grade = 'A'; // 16 bits, Unicode character (0 to 65,535)
boolean isActive = true; // 1 bit, true or false
When to Use Each
// byte: small numbers, raw data, network protocols
byte[] buffer = new byte[1024];
byte flags = 0b10101010;
// short: moderate numbers, memory optimization
short[] temperatures = new short[365];
// int: most common integer type, array indices, loops
int count = 100;
int[] numbers = new int[1000];
// long: large numbers, timestamps, IDs
long timestamp = System.currentTimeMillis();
long population = 8_000_000_000L;
// float: memory-efficient decimals, graphics
float red = 0.5f;
float[] matrix = new float[16];
// double: precise decimals, most calculations
double pi = Math.PI;
double salary = 150000.50;
// char: characters, Unicode support
char letter = 'A';
char emoji = '\u2764';
char chinese = '\u4F60';
// boolean: flags, conditions
boolean isReady = true;
boolean hasPermission = false;
Size Comparison
type bits bytes range
byte 8 1 -128 to 127
short 16 2 -32,768 to 32,767
int 32 4 -2,147,483,648 to 2,147,483,647
long 64 8 -9.2 × 10^18 to 9.2 × 10^18
float 32 4 ±3.4 × 10^38 (7 decimal digits)
double 64 8 ±1.7 × 10^308 (15 decimal digits)
char 16 2 0 to 65,535
boolean 1 varies true or false
Ranges and Overflow
Numeric Ranges
// Understanding limits
public class Ranges {
public static void main(String[] args) {
// Byte range
System.out.println("Byte: " + Byte.MIN_VALUE + " to " + Byte.MAX_VALUE);
// Output: -128 to 127
// Short range
System.out.println("Short: " + Short.MIN_VALUE + " to " + Short.MAX_VALUE);
// Output: -32768 to 32767
// Int range
System.out.println("Int: " + Integer.MIN_VALUE + " to " + Integer.MAX_VALUE);
// Output: -2147483648 to 2147483647
// Long range
System.out.println("Long: " + Long.MIN_VALUE + " to " + Long.MAX_VALUE);
// Output: -9223372036854775808 to 9223372036854775807
// Float precision
System.out.println("Float: " + Float.MIN_VALUE + " to " + Float.MAX_VALUE);
// Double precision
System.out.println("Double: " + Double.MIN_VALUE + " to " + Double.MAX_VALUE);
}
}
Integer Overflow
// Overflow wraps around silently!
public class Overflow {
public static void main(String[] args) {
int maxInt = Integer.MAX_VALUE; // 2,147,483,647
System.out.println(maxInt + 1); // Output: -2,147,483,648 (wraps!)
// Byte overflow
byte b = 127;
b++; // Output: -128
// Detect overflow
int a = Integer.MAX_VALUE;
int result = a + 1;
System.out.println(result < a); // true (overflow detected)
// Safe addition with overflow check
public static int safeAdd(int a, int b) {
if ((b > 0 && a > Integer.MAX_VALUE - b) ||
(b < 0 && a < Integer.MIN_VALUE - b)) {
throw new ArithmeticException("Integer overflow");
}
return a + b;
}
}
}
Floating Point Precision Issues
// Precision problems with float/double
public class Precision {
public static void main(String[] args) {
// float precision issue
float f1 = 0.1f;
float f2 = 0.2f;
System.out.println(f1 + f2); // 0.3 (not exactly 0.3!)
// Double precision issue
double d1 = 0.1;
double d2 = 0.2;
System.out.println(d1 + d2); // 0.30000000000000004
// Never use == with doubles!
System.out.println(d1 + d2 == 0.3); // false!
// Correct comparison
double epsilon = 1e-9;
System.out.println(Math.abs(d1 + d2 - 0.3) < epsilon); // true
// Use BigDecimal for financial calculations
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
System.out.println(bd1.add(bd2)); // 0.3 (exact)
}
}
Type Literals
public class Literals {
public static void main(String[] args) {
// Decimal
int decimal = 42;
// Binary (0b prefix)
int binary = 0b101010; // 42
// Octal (0 prefix)
int octal = 052; // 42
// Hexadecimal (0x prefix)
int hex = 0x2A; // 42
// Underscores for readability (Java 7+)
int million = 1_000_000;
long creditCard = 1234_5678_9012_3456L;
// Scientific notation
double million = 1e6; // 1,000,000
double micro = 1e-6; // 0.000001
// Character literals
char a = 'A';
char digit = '9';
char unicode = '\u0041'; // 'A'
char newline = '\n';
char tab = '\t';
// String literals (not primitive, but common)
String name = "Amazon";
String path = "C:\\\Users"; // escaped backslash
}
}
Default Values
Primitive Default Values
Instance and Class Variables
public class DefaultValues {
// All instance variables have defaults
byte byteDefault; // 0
short shortDefault; // 0
int intDefault; // 0
long longDefault; // 0L
float floatDefault; // 0.0f
double doubleDefault; // 0.0d
char charDefault; // '\u0000' (null character)
boolean boolDefault; // false
static int staticDefault; // 0 (same defaults)
public void printDefaults() {
System.out.println("byte: " + byteDefault + " (" + (byteDefault == 0) + ")");
System.out.println("int: " + intDefault + " (" + (intDefault == 0) + ")");
System.out.println("double: " + doubleDefault + " (" + (doubleDefault == 0.0) + ")");
System.out.println("boolean: " + boolDefault + " (" + (!boolDefault) + ")");
System.out.println("char: " + (int)charDefault + " (" + (charDefault == '\u0000') + ")");
}
public static void main(String[] args) {
DefaultValues dv = new DefaultValues();
dv.printDefaults();
}
}
Local Variables - No Defaults!
public class LocalDefaults {
public void method() {
// Local variables MUST be initialized
int x;
// System.out.println(x); // COMPILE ERROR!
x = 10; // Now it's initialized
System.out.println(x); // OK
// This applies to all primitives
boolean flag;
// if (flag) { } // COMPILE ERROR!
flag = true;
if (flag) { } // OK
}
}
Summary Table
| Type | Default Value | Size | Range |
|---|---|---|---|
| byte | 0 | 1 byte | -128 to 127 |
| short | 0 | 2 bytes | -32,768 to 32,767 |
| int | 0 | 4 bytes | -2^31 to 2^31-1 |
| long | 0L | 8 bytes | -2^63 to 2^63-1 |
| float | 0.0f | 4 bytes | ±3.4×10^38 |
| double | 0.0d | 8 bytes | ±1.7×10^308 |
| char | '\u0000' | 2 bytes | 0 to 65,535 |
| boolean | false | 1 bit | true/false |
Type Conversion
Widening Conversion (Implicit)
Automatic conversion from smaller to larger type. No data loss.
public class Widening {
public static void main(String[] args) {
// Widening chain: byte → short → int → long → float → double
byte b = 10;
short s = b; // byte to short (implicit)
int i = s; // short to int (implicit)
long l = i; // int to long (implicit)
float f = l; // long to float (implicit)
double d = f; // float to double (implicit)
// char can widen to int
char c = 'A';
int charToInt = c; // char to int (implicit)
System.out.println("All widening conversions work!");
}
}
Narrowing Conversion (Explicit)
Requires explicit cast. May lose data.
public class Narrowing {
public static void main(String[] args) {
// Must use cast for narrowing
double d = 3.99;
int i = (int) d; // 3 (truncates, not rounds)
long l = 1000;
byte b = (byte) l; // May overflow!
// Data loss examples
int big = 130;
byte small = (byte) big; // -126 (overflow!)
// Float precision loss
float f = 123456.789f;
int exact = (int) f; // 123456 (precision lost)
System.out.println("Narrowing conversions:");
System.out.println("3.99 → int: " + i); // 3
System.out.println("130 → byte: " + small); // -126
System.out.println("123456.789f → int: " + exact); // 123456
}
}
Conversion Rules
WIDENING (implicit):
byte → short → int → long → float → double
char → int → long → float → double
NARROWING (explicit cast required):
double → float → long → int → short → byte
Common Conversion Patterns
// String to number
String numStr = "42";
int num = Integer.parseInt(numStr);
double d = Double.parseDouble("3.14");
// Number to String
String fromInt = String.valueOf(42);
String fromDouble = Double.toString(3.14);
String concatenated = "" + 42; // also works
// char to int and back
char ch = 'A';
int ascii = ch; // 65
char back = (char) ascii; // 'A'
// boolean conversions
boolean b = true;
// Cannot convert boolean to/from other types!
// int i = (int) b; // COMPILE ERROR
// boolean fromInt = (boolean) 1; // COMPILE ERROR
Practice Problems
What is the output of this code?
Example:
Input: public class Overflow { public static void main(String[] args) { int a = Integer.MAX_VALUE; int b = 1; System.out.println(a + b); } }
Output: -2147483648
Integer overflow wraps around to MIN_VALUE.
Optimal Solution — O(1) time, O(1) space
Understand integer overflow behavior
public class Overflow {
public static void main(String[] args) {
int a = Integer.MAX_VALUE; // 2147483647
int b = 1;
System.out.println(a + b); // -2147483648 (wraps to MIN_VALUE)
}
}Edge Cases:
- Long overflow
- Byte overflow
What is the output of this code?
Example:
Input: public class Conversion { public static void main(String[] args) { double d = 9.78; int i = (int) d; System.out.println(i); } }
Output: 9
Casting double to int truncates the decimal part.
Optimal Solution — O(1) time, O(1) space
Understand truncation behavior
public class Conversion {
public static void main(String[] args) {
double d = 9.78;
int i = (int) d; // Truncates to 9 (not rounding)
System.out.println(i); // 9
}
}Edge Cases:
- Rounding vs truncation
- Negative numbers
Find and fix the bug in this code.
Example:
Input: public class Bug { public static void main(String[] args) { double a = 0.1 + 0.2; double b = 0.3; if (a == b) { System.out.println("Equal"); } else { System.out.println("Not equal"); } } }
Output: Not equal
0.1 + 0.2 is not exactly 0.3 due to floating-point precision. Use epsilon comparison.
Optimal Solution — O(1) time, O(1) space
Use epsilon for floating-point comparison
public class Bug {
public static void main(String[] args) {
double a = 0.1 + 0.2;
double b = 0.3;
double epsilon = 1e-9;
if (Math.abs(a - b) < epsilon) {
System.out.println("Equal");
} else {
System.out.println("Not equal");
}
}
}Edge Cases:
- Using BigDecimal for exact values
- Float vs double precision
Quiz
1. What is the size of an int in Java?
2. What is the default value of a boolean instance variable?
3. What happens when you cast double 3.99 to int?
4. Which conversion is implicit (no cast required)?
Flashcards
Question
What are the 8 primitive types in Java?
Click to reveal answer
Answer
byte (8-bit), short (16-bit), int (32-bit), long (64-bit), float (32-bit), double (64-bit), char (16-bit), boolean (1-bit)
Question
What is the range of byte?
Click to reveal answer
Answer
-128 to 127 (8 bits, signed). Use when memory is critical.
Question
Why should you avoid == with doubles?
Click to reveal answer
Answer
Floating-point precision issues cause 0.1 + 0.2 != 0.3. Use epsilon comparison instead.
Question
What is integer overflow?
Click to reveal answer
Answer
When arithmetic exceeds the type's range, it wraps around silently. E.g., Integer.MAX_VALUE + 1 = Integer.MIN_VALUE.
Question
What is Primitive Data Types?
Click to reveal answer
Answer
Primitive Data Types is a key concept in Java programming.
Revision Notes
Key Takeaways
- 1.int is the default choice for integers, double for decimals
- 2.Use long for large numbers (timestamps, IDs)
- 3.Never use == to compare floating-point numbers
- 4.Integer overflow wraps around silently - be careful
- 5.BigDecimal for financial calculations requiring exact precision
Interview Tips
- •Know the size and range of each primitive type
- •Understand implicit vs explicit type conversion
- •Be aware of integer overflow in algorithm design
- •Use appropriate types to prevent bugs (e.g., long for timestamps)
Cheat Sheet
Primitive Types Cheat Sheet
| Type | Size | Range | Default |
|---|---|---|---|
| byte | 8-bit | -128 to 127 | 0 |
| short | 16-bit | -32,768 to 32,767 | 0 |
| int | 32-bit | -2^31 to 2^31-1 | 0 |
| long | 64-bit | -2^63 to 2^63-1 | 0L |
| float | 32-bit | ±3.4×10^38 | 0.0f |
| double | 64-bit | ±1.7×10^308 | 0.0d |
| char | 16-bit | 0 to 65,535 | '\u0000' |
| boolean | 1-bit | true/false | false |
Widening: byte → short → int → long → float → double
Narrowing: Requires explicit cast, may lose data