Primitives, Wrappers, Type Casting, and Autoboxing

1. 8 Primitive Data Types

Java defines eight primitive data types. They are predefined by the language and named by a reserved keyword. Primitives represent raw values and do not share state like objects do. They can be broken down into four distinct categories:

Primitive Specifications Matrix

Data Type Size Default Value Range / Value Definition
byte 1 byte (8 bits) 0 -128 to 127
short 2 bytes (16 bits) 0 -32,768 to 32,767
int 4 bytes (32 bits) 0 -231 to 231-1 (~2 Billion)
long 8 bytes (64 bits) 0L -263 to 263-1
float 4 bytes (32 bits) 0.0f Up to 6-7 decimal digits of precision
double 8 bytes (64 bits) 0.0d Up to 15 decimal digits of precision
char 2 bytes (16 bits) '\u0000' Single Unicode character (0 to 65,535)
boolean Virtual Machine Dependent false true or false only

2. Primitive Data Types vs. Wrapper Types

A wrapper class is a class that encapsulates (wraps) a primitive data type into an object

Comparison Matrix

Feature Primitive Type Wrapper Class
Examples int, char, double, boolean Integer, Character, Double, Boolean
Memory Allocation Stored directly on the Stack Stored as objects on the Heap
Nullability Cannot be null (Defaults to 0, false, etc.) Can be null (Leads to NullPointerException if not handled)
Methods No methods associated with them Contains utility methods (e.g., Integer.parseInt())
Exam Tip: Remember that primitives always start with a lowercase letter (e.g., float), whereas wrapper classes start with an uppercase letter because they are actual classes (e.g., Float).

3. Type Casting in Java

Type casting is assigning a value of one primitive data type to another type. In Java, casting is broadly split into two types based on memory size and precision data loss.

A. Widening Casting (Implicit Conversion)

Done automatically by Java when passing a smaller data type to a larger data type size. There is no data loss.

byteshortcharintlongfloatdouble

public class WideningExample {
    public static void main(String[] args) {
        int myInt = 9;
        double myDouble = myInt; // Automatic casting: int to double

        System.out.println(myInt);      // Outputs 9
        System.out.println(myDouble);   // Outputs 9.0
    }
}

B. Narrowing Casting (Explicit Conversion)

Must be done manually by placing the type in parentheses in front of the value. This can cause data loss or precision truncation.

doublefloatlongintcharshortbyte

public class NarrowingExample {
    public static void main(String[] args) {
        double myDouble = 9.78d;
        int myInt = (int) myDouble; // Manual casting: double to int

        System.out.println(myDouble);   // Outputs 9.78
        System.out.println(myInt);      // Outputs 9 (Fractional part is lost!)
    }
}
Warning (Integer Overflow): If you cast a number that is larger than the maximum capacity of the target data type, the bits will truncate, resulting in unexpected/garbage values.

4. Autoboxing and Unboxing

To eliminate boilerplates, the Java compiler automates the conversion between primitives and wrappers. This feature was introduced in Java 5.

Autoboxing

The automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. (e.g., converting an int to an Integer).

public class AutoboxingExample {
    public static void main(String[] args) {
        int primitiveInt = 25;
        
        
        // Autoboxing (Modern Java automatically handles this)
        Integer modernWay = primitiveInt; 
    }
}

Unboxing

The automatic conversion of wrapper types back to their corresponding primitive types (e.g., converting an Integer to an int).

public class UnboxingExample {
    public static void main(String[] args) {
        Integer objectInteger = new Integer(100);
        
        
        
        // Unboxing (Modern Java)
        int modernWay = objectInteger; 
        
        System.out.println("Value: " + modernWay);
    }
}
Viva Question Catch: Performance issues can occur if autoboxing/unboxing happens inside heavy, multi-million iteration loops. It repeatedly creates wrapper objects behind the scenes, triggering heavy Garbage Collection.