Skip to main content

Command Palette

Search for a command to run...

Java Series #4: Wrapper Classes and Static Members

Autoboxing, Wrapper Classes & Static Blocks

Published
•4 min read•View as Markdown
Java Series #4: Wrapper Classes and Static Members
A
I’m a Full-stack Developer who enjoys turning ideas into simple and useful experiences. I like building clean user interfaces, exploring AI, and understanding how things work behind the scenes. From creating websites to trying out new technologies, I’m always curious and learning something new. Next.js, Node.js, MongoDB, and Java Spring Boot are the tools I use regularly. I enjoy experimenting with projects, sharing what I learn, and improving with every build. Vibing + Thinking.

This article covers concepts that often look small in syntax but have major impact on how Java handles memory, objects, collections, and execution flow.

1. Why Java Needs Wrapper Classes

Primitive types (int, char, double, boolean, etc.) are not objects.
But many parts of the Java ecosystem require objects, not primitives.

Reasons Java introduced Wrapper Classes

  1. Collections work only with objects
    ArrayList<int> is illegal → use ArrayList<Integer>

  2. Object Methods
    Wrappers allow primitives to behave like objects and support:

    • equals()

    • hashCode()

    • toString()

    • comparison methods (Integer.compare, etc.)

  3. Multithreading Synchronization
    Wrappers can be synchronized; primitives cannot.

  4. Generic APIs (java.util, streams)
    The entire java.util package deals with objects.

Wrapper class equivalents
int → Integer
double → Double
boolean → Boolean
char → Character
long → Long
byte → Byte
short → Short
float → Float


2. Autoboxing and Unboxing

Autoboxing

Automatic conversion of primitive → wrapper object.

Example:

int a = 10;
Integer x = a;     // Autoboxing

Behind the scenes:

Integer x = Integer.valueOf(a);

Unboxing

Automatic conversion wrapper → primitive.

Example:

Integer y = 20;
int b = y;        // Unboxing

Behind the scenes:

int b = y.intValue();

3. Why Autoboxing/Unboxing Is Important

Scenario 1: Using collections

List<Integer> list = new ArrayList<>();
list.add(5);           // int -> Integer (autobox)
int value = list.get(0); // Integer -> int (unbox)

Scenario 2: Working with frameworks

Frameworks like Hibernate, Spring, Collections API, Streams — all expect objects.

Scenario 3: Comparison traps

Autoboxing sometimes leads to unexpected outputs:

Integer a = 100;
Integer b = 100;

System.out.println(a == b);   // true (cached)

But:

Integer x = 1000;
Integer y = 1000;

System.out.println(x == y);   // false (not cached)

Reason: Integer Cache of -128 to 127.


4. Custom Wrapper Classes (User Defined Wrappers)

Sometimes you create a wrapper around a primitive or logic to encapsulate behavior.

Example

class Temperature {
    private double value;

    Temperature(double value) {
        this.value = value;
    }

    public double toCelsius() {
        return (value - 32) * 5/9;
    }

    public double getValue() {
        return value;
    }
}

Use-case: Data validation, domain-specific conversions, or creating abstractions.


5. Static Blocks in Java

Static blocks are executed once per class, at the time of class loading.
They are used for class-level initialization.

Execution Flow

  1. Class is loaded → static variables initialized

  2. Static block executes

  3. Main method runs

  4. Object creation triggers:

    • Instance variables initialization

    • Initializer block

    • Constructor

Example

class Demo {

    static int a = 10;

    static {
        System.out.println("Static Block Executed");
        a = 20;   // allowed
    }

    {
        System.out.println("Initializer Block Executed");
    }

    Demo() {
        System.out.println("Constructor Executed");
    }

    public static void main(String[] args) {
        System.out.println("Main Method Starts");
        Demo d = new Demo();
    }
}

Output

Static Block Executed
Main Method Starts
Initializer Block Executed
Constructor Executed

Key Points

  • Static block runs only once

  • Cannot access instance variables

  • Ideal for loading configs, static resources, JDBC drivers, logging setups

  • Instance initializer block runs before every constructor call


6. Static Variables vs Instance Variables in Init Blocks

FeatureStatic BlockInitializer Block
When executedClass loadEvery object creation
Can use static variablesYesYes
Can use instance variablesNoYes
Executes before constructorYesYes

7. Common Interview Concepts

Why do we avoid using too many wrapper objects?

Because wrappers are stored in heap, cost more memory, and unboxing/boxing has performance cost.

Difference between == and .equals() for Integer?

  • == compares references

  • .equals() compares values

Can static blocks throw exceptions?

Yes, but must be handled inside the block.

Why can’t static blocks access this or instance members?

Because object is not created yet; only class is loaded.

When does static block run in relation to main()?

Before main(), once per class.


8. Final Summary

  • Wrapper classes allow primitives to function as objects.

  • Autoboxing/unboxing simplify conversions but may cause hidden performance issues.

  • Custom wrappers encapsulate domain-specific behaviors.

  • Static blocks handle one-time class initialization.

  • Understanding these is important for collections, multithreading, frameworks, and memory-efficient coding.