Wrapper Classes, Autoboxing & Packages
Wrapper classes let primitive numbers act like objects, and packages plus access modifiers keep big projects tidy and safe.
What you will learn
- Use wrapper classes and let autoboxing convert for you
- Organise code into packages
- Choose the right access modifier for fields and methods
Two kinds of value in Java
Java has two families of types. Primitives like int, double and boolean are the plain, lightweight values you have used since the start — they just hold a number or a true/false. Objects are richer things built from classes (like String or Dog) that can carry methods.
Sometimes you need a primitive to behave like an object — most importantly because collections such as ArrayList can only hold objects, never raw primitives. For each primitive, Java provides a matching wrapper class: a tiny object that wraps one primitive value.
| Primitive | Wrapper class |
|---|---|
int | Integer |
double | Double |
boolean | Boolean |
char | Character |
long | Long |
Autoboxing: Java converts for you
Autoboxing is Java automatically turning a primitive into its wrapper object when needed; unboxing is the reverse, turning a wrapper back into a primitive. You rarely write the conversion yourself — Java does it silently. Here is an ArrayList holding numbers, which only works because each int is autoboxed into an Integer.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> scores = new ArrayList<>();
scores.add(80); // autoboxing: int 80 becomes Integer
scores.add(95);
scores.add(60);
int first = scores.get(0); // unboxing: Integer becomes int
int total = 0;
for (int s : scores) { // each Integer unboxed to int
total = total + s;
}
System.out.println("First score: " + first);
System.out.println("Total: " + total);
}
}Note: Output:
First score: 80
Total: 235
We wrote plain numbers like 80, but the list stores Integer objects — Java autoboxed each one for us. When we read them back with get(0) or in the loop, Java unboxed them into plain int values so the maths works. You almost never see the conversion; it just happens.
Wrapper classes also carry handy helper methods. A very common one converts text into a number — exactly what you need after reading a line from a file or the web:
String typed = "42";
int n = Integer.parseInt(typed); // text to int
double d = Double.parseDouble("3.14");
System.out.println(n + 8);
System.out.println(d);Note: Output:
50
3.14
Integer.parseInt("42") read the text "42" and gave back the number 42, so n + 8 is 50. Double.parseDouble does the same for decimals. These parse... methods live on the wrapper classes and are how you convert user input or file text into real numbers.
Watch out: A wrapper can be null (it is an object), but a primitive cannot. If you unbox a null Integer into an int, Java throws a NullPointerException at runtime. Prefer plain primitives unless you specifically need an object (for a collection) or the possible absence of a value.
Packages: folders for your classes
A real project has dozens of classes. A package is a named group of related classes — think of it as a folder that also prevents name clashes (two classes can both be called Account if they live in different packages). You declare the package on the very first line of a file.
package com.codingclave.bank;
public class Account {
// ... fields and methods ...
}Note: Output:
(No output — this is structure, not behaviour. The line package com.codingclave.bank; says this Account belongs to that package, and the file lives in folders com/codingclave/bank/ to match. The usual naming is your reversed web address, lowercase.)
To use a class from another package, you import it at the top — exactly as you already did with import java.util.Scanner;. The Scanner you have used all along lives in the java.util package; importing is just borrowing a class from another package by its full name once, so you can use its short name afterwards.
Access modifiers: who is allowed in
An access modifier controls which code can see a field, method or class. You met private and public in encapsulation. Here is the full set, from most open to most closed:
| Modifier | Who can access it |
|---|---|
public | Any code, anywhere |
protected | The same package, plus subclasses (even in other packages) |
| (none — called default) | Only code in the same package |
private | Only inside the same class |
The guiding rule is least access: make everything as closed as it can be, and only open it up when something outside genuinely needs it. Fields are usually private; the methods other classes must call are public.
Tip: When you write no modifier at all, you get default (also called package-private) access — visible only within the same package. It is easy to forget this exists, but it is a sensible middle ground for helper classes that should not leak outside their package.
Q. Why can an ArrayList<Integer> store numbers even though a list cannot hold primitives?
int into an Integer object when you add it, and unboxes it back to an int when you read it.✍️ Practice
- Make an
ArrayList<Double>of three prices, add them up in a loop, and print the total — letting autoboxing do the conversions. - Use
Integer.parseIntto turn the Strings "10", "20" and "30" into numbers and print their sum.
🏠 Homework
- Write a short note explaining, in your own words, the four access levels (public, protected, default, private) and give one realistic example of when you would use each in a small project.