🏗️ Classes & Objects · Intermediate

Packages & imports in Java

Package naming, import, static import, java.lang is automatic, name clashes.

🧩 The mysteryThe JDK contains two classes named Date and two named List. Java never mixes them up — as long as you tell it where to look.

Packages: full names for classes

A package groups related classes and gives each a unique full name, like java.util.List. The package line goes first in a file. By convention, names are your reversed internet domain in lowercase: com.example.shop.

package com.example.shop;
 
public class Item { }
// full name: com.example.shop.Item

Imports: short names

import java.util.List; imports one type. import java.util.*; imports all types of that one package on demand. And java.lang — String, Math, System, Integer — is imported automatically, everywhere.

import java.util.List;   // one type
import java.util.*;      // whole package
// String, Math: no import needed
⚠️ The trap

Packages aren't nested

java.util and java.util.function look related, but they're completely separate packages. import java.util.*; does not give you Function — import java.util.function.* too.

import java.util.*;
Function<String, Integer> f; // error!
🤔 Think first

Two Dates walk into a file

With import java.util.*; and import java.sql.*;, writing Date d; fails: "reference to Date is ambiguous". Will swapping the import order help? What's the fix?

Think about it, then reveal the answer

Swapping does nothing — import order has no meaning in Java. Add a single-type import, import java.util.Date;: it beats any wildcard, so Date becomes unambiguous. (Or write the full name java.sql.Date.)

Static and module imports

import static java.lang.Math.max; lets you call max(a, b) without Math.. Java 25 adds module imports (JEP 511): import module java.base; brings in every public type from all packages that module exports. Compact source files do this automatically — that's why these lessons use List with no imports.

🔮 Predict it

Static import in action

What does this print?

import static java.lang.Math.*;
 
void main() {
    System.out.println(max(3, 9) + abs(-2));
}
  1. 11
  2. 92
  3. Compile error
Show the answer

11. The static wildcard import makes max and abs usable without Math.: 9 + 2 = 11.

💼 In the real world

In real projects

Big codebases live and die by package structure. Maven artifacts use the same reversed-domain idea for group IDs, IDEs manage imports for you, and teams argue endlessly about wildcard vs explicit imports. Name clashes like Date or List (also in java.awt!) show up weekly.

Key takeaways

  1. package com.example.shop; goes first in a file
  2. java.lang (String, Math...) needs no import
  3. import java.util.*; does NOT include subpackages
  4. A single-type import beats a wildcard on name clashes
🤯 Did you know?

The two clashing Dates are actually family: java.sql.Date extends java.util.Date.

Practice questions

Does import java.util.*; let you use java.util.function.Function by its short name?

  1. No: packages are not nested, so subpackages must be imported separately
  2. Yes: the * includes every subpackage
  3. Yes, but only in the same module
  4. No: wildcard imports are not allowed
Check your answer

No: packages are not nested, so subpackages must be imported separately. java.util and java.util.function are completely separate packages despite the similar names. The wildcard only covers types directly in java.util.

With these imports, Date d; fails: "reference to Date is ambiguous". Best fix?

import java.util.*;
import java.sql.*;
 
Date d;
  1. Add import java.util.Date; - a single-type import wins
  2. Swap the order of the two imports
  3. Write date in lowercase
  4. Add import java.lang.*;
Check your answer

Add import java.util.Date; - a single-type import wins. Both packages contain a Date. A single-type import shadows wildcard imports, so the name becomes unambiguous. Import order never matters.

Next: building objects that can never change — just like String itself.