Primitives, Wrappers & Autoboxing

Primitives, Wrapper class ও Autoboxing

Read: ~30 min Intermediate 5 practice problems Live code runner

1. Two Worlds — Primitives and Objects

Java has two kinds of value. Primitive types hold a raw number or character directly on the stack — fast, small, no object overhead. Wrapper classes (Integer, Double, …) are real Java objects living on the heap, and they work with the Collections framework. Autoboxing is Java's automatic conversion between the two — convenient, but never free.

Java-তে মান দুই ধরনের। Primitive — stack-এ সরাসরি মান (দ্রুত, ছোট, কোনো object নয়)। Wrapper class — heap-এ object হিসেবে (Integer, Double ইত্যাদি, Collections-এ কাজে আসে)। Autoboxing দুটির মধ্যে স্বয়ংক্রিয় রূপান্তর — সুবিধা দেয়, কিন্তু cost আছে।

2. The 8 Primitive Types

PrimitiveSizeRangeWrapperDefault
byte8 bits−128 … 127Byte0
short16 bits−32 768 … 32 767Short0
int32 bits~ −2.1 × 10⁹ … 2.1 × 10⁹Integer0
long64 bits~ ±9.2 × 10¹⁸Long0L
float32 bits~ 7 decimal digitsFloat0.0f
double64 bits~ 15 decimal digitsDouble0.0
char16 bitsUnicode code unit 0 … 65 535Character'\u0000'
boolean—true / falseBooleanfalse
আটটি primitive — byte, short, int, long পূর্ণসংখ্যা; float, double দশমিক; char একটি Unicode অক্ষর; boolean হাঁ/না। প্রত্যেকের আলাদা size এবং wrapper class আছে।

3. Literals — Writing Values

Main.java
class Main {
    public static void main(String[] args) {
        int    dhakaPop  = 22_000_000;      // underscores for readability
        long   bdReserve = 24_500_000_000L;  // L suffix for long
        double pi        = 3.14159;
        float  rate      = 7.25f;           // f suffix for float
        char   grade     = 'A';
        boolean passed   = true;

        int hex = 0xFF;        // 255 in hex
        int bin = 0b1010;      // 10 in binary
        int oct = 0777;        // 511 in octal (leading zero)

        System.out.println(dhakaPop + " " + bdReserve + " " + pi);
        System.out.println(rate + " " + grade + " " + passed);
        System.out.println("Bases: " + hex + " " + bin + " " + oct);
    }
}
Number-এ _ ব্যবহার করে পড়তে সহজ করা যায় (22_000_000)। L long, f float; 0x hex, 0b binary, শুরুতে শুধু 0 octal — এই শেষটি দুর্ঘটনার উৎস, সতর্ক থাকুন।

4. Stack vs Heap — Where Values Live

STACK int x = 42 double d = 3.14 Integer ref ─┐ HEAP Integer object value = 42 Figure 5.1 — Primitive stack-এ সরাসরি বসে। Wrapper object heap-এ থাকে; stack-এ শুধু reference।
Stack: method call-এর সঙ্গে জন্ম ও মৃত্যু, খুব দ্রুত। primitive variable সরাসরি stack-এ। Heap: সব object (Integer সহ) এখানে, Garbage Collector পরিষ্কার করে। wrapper variable মানে stack-এ একটি reference যেটি heap-এর object-কে point করে।

5. Wrapper Classes — When Collections Demand Objects

Java's Collections (List, Map, Set …) only store objects, not primitives. You can't have a List<int> — you need List<Integer>. That's the main reason wrappers exist.

Main.java
import java.util.*;

class Main {
    public static void main(String[] args) {
        // Collections only accept objects — hence wrappers
        List<Integer> ages = new ArrayList<>();
        ages.add(21);         // autobox: int → Integer
        ages.add(22);
        ages.add(19);

        int total = 0;
        for (int a : ages) total += a;   // unbox: Integer → int
        System.out.println("Sum = " + total);

        // Useful helpers on wrappers
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.parseInt("123"));
        System.out.println(Integer.toBinaryString(42));
    }
}
Collections (List/Map/Set) object নেয়, primitive নেয় না — তাই Integer, Double-এর মতো wrapper লাগে। wrapper-এ কিছু দরকারি utility-ও আছে — parseInt, MAX_VALUE, toBinaryString ইত্যাদি।

6. The Real Cost of Autoboxing

Autoboxing looks free, but each box creates a small object (or fetches one from the cache). Do it millions of times in a hot loop and it shows up in profilers.

Main.java
class Main {
    public static void main(String[] args) {
        final int N = 5_000_000;

        long t1 = System.nanoTime();
        long sum1 = 0;
        for (int i = 0; i < N; i++) sum1 += i;       // all primitives
        long t2 = System.nanoTime();

        Long sum2 = 0L;                                // boxed!
        for (int i = 0; i < N; i++) sum2 += i;       // autobox every iteration
        long t3 = System.nanoTime();

        System.out.printf("primitive long: %d ns%n", t2 - t1);
        System.out.printf("boxed    Long : %d ns%n", t3 - t2);
        System.out.printf("slowdown      : %.1fx%n", (t3 - t2) / (double)(t2 - t1));
    }
}
Rule of thumb: prefer int / long / double in arithmetic-heavy hot loops. Use wrappers when a collection or API demands them.

সরল নিয়ম — হট লুপে primitive ব্যবহার করুন, Collection / API wrapper চাইলেই কেবল wrapper।

7. The == Gotcha on Wrappers

== on wrapper objects compares references, not values. Java caches Integers from −128 to 127, so small values may compare equal by coincidence — bigger ones usually won't. Always use .equals() on wrappers, or unbox first.

Main.java
class Main {
    public static void main(String[] args) {
        Integer a = 100,  b = 100;    // cached
        Integer c = 200,  d = 200;    // not cached

        System.out.println("100 == 100 ? " + (a == b));   // likely true
        System.out.println("200 == 200 ? " + (c == d));   // false!
        System.out.println("200.equals(200)? " + c.equals(d)); // true
    }
}
Wrapper object-এ == reference মেলায়, মান নয়। Java −128..127 পর্যন্ত Integer cache করে, তাই ছোট মান দৈবক্রমে মিলে যায়, বড় মান প্রায়ই মেলে না। wrapper-এর মান মেলাতে সবসময় .equals() ব্যবহার করুন।

8. Vocabulary

TermMeaningবাংলায়
PrimitiveRaw value type; lives on the stack.মূল মান, stack-এ থাকে।
Wrapper classObject form of a primitive (Integer, Double …).primitive-এর object রূপ।
AutoboxingAutomatic primitive → wrapper conversion.স্বয়ংক্রিয় primitive → wrapper রূপান্তর।
UnboxingWrapper → primitive (can throw NPE if null).wrapper → primitive, null হলে NPE হতে পারে।
Integer cacheJVM caches Integer objects for −128 … 127.ছোট Integer object JVM cache করে।
LiteralDirectly-written value in source code.কোডে সরাসরি লেখা মান।

9. Practice Problems

  1. Print the max and min value of int and long using the wrapper constants.
    Integer এবং Long-এর MAX/MIN VALUE print করুন।
    ✨ Show Answer (উত্তর দেখুন)
    Main.java
    class Main {
        public static void main(String[] args) {
            System.out.println("int max : " + Integer.MAX_VALUE);
            System.out.println("int min : " + Integer.MIN_VALUE);
            System.out.println("long max: " + Long.MAX_VALUE);
            System.out.println("long min: " + Long.MIN_VALUE);
        }
    }
  2. What happens when you compute Integer.MAX_VALUE + 1? Try it and explain.
    Integer.MAX_VALUE + 1 হলে কী হবে — চালিয়ে ব্যাখ্যা করুন।
    ✨ Show Answer (উত্তর দেখুন)
    Main.java
    class Main {
        public static void main(String[] args) {
            int v = Integer.MAX_VALUE + 1;
            System.out.println(v);
            System.out.println(v == Integer.MIN_VALUE);
        }
    }

    Integer overflow wraps around — the result is Integer.MIN_VALUE. Java does not throw on signed overflow; use Math.addExact if you want an exception, or long if the value might exceed the int range.

  3. Parse the string "2025" into an int, add 5 to it, and print the result.
    "2025" string-কে int-এ রূপান্তর করে ৫ যোগ করে print করুন।
    ✨ Show Answer (উত্তর দেখুন)
    Main.java
    class Main {
        public static void main(String[] args) {
            int year = Integer.parseInt("2025");
            System.out.println(year + 5);
        }
    }
  4. Explain in 2 sentences why an Integer list uses more memory than an int[] with the same values.
    একই মানের int[]-এর তুলনায় List<Integer> কেন বেশি memory নেয়?
    ✨ Show Answer (উত্তর দেখুন)

    Answer: An int[] stores raw 4-byte ints contiguously — just the data. A List<Integer> stores references to separate Integer objects on the heap, each with its own object header (typically 16 bytes) plus the boxed int — so the per-element cost is roughly 5× and cache locality is much worse.

  5. Use a char and a boolean together: if the grade char is 'A' or 'B', set passed = true, else false. Run it for a few letters.
    grade char-এর উপর ভিত্তি করে boolean passed বসিয়ে print করুন।
    ✨ Show Answer (উত্তর দেখুন)
    Main.java
    class Main {
        public static void main(String[] args) {
            char[] grades = { 'A', 'B', 'C', 'F' };
            for (char g : grades) {
                boolean passed = (g == 'A' || g == 'B');
                System.out.println("Grade " + g + " → passed = " + passed);
            }
        }
    }

Summary — Module 05

Java has 8 primitives and 8 matching wrapper classes. Primitives live on the stack and are fast; wrappers live on the heap and work with the Collections framework. Autoboxing is the automatic bridge between the two — but it has real performance and memory cost in hot paths. Use .equals() not == on wrappers. Know the Integer cache (−128..127) so you are never surprised.

৮টি primitive, ৮টি wrapper। Primitive দ্রুত ও stack-এ; wrapper heap-এ ও Collections-এ লাগে। Autoboxing সুবিধাজনক কিন্তু hot loop-এ cost আছে। wrapper-এ .equals() ব্যবহার করুন। Integer cache (−128..127) মনে রাখুন।

Next Module → Variables, scope, final, and Java's static type system.