Java import Statement
Java import Statement
Every time you use ArrayList, HashMap, or LocalDate in Java without writing the full java.util.ArrayList every single time, the import statement is doing that work for you. Without imports, every reference to any class outside java.lang would require the full package path — java.util.ArrayList<java.util.HashMap<java.lang.String, java.util.List<java.lang.Integer>>> instead of ArrayList<HashMap<String, List<Integer>>>.
The import statement tells the compiler where to find a class by its simple name. It does not load the class into memory or make the program heavier — it is purely a compile-time instruction that resolves a short name to a fully qualified one.
How import Works
Without import — full class name required everywhere: java.util.ArrayList<String> list = new java.util.ArrayList<>(); java.util.Collections.sort(list); With import — short name works: import java.util.ArrayList; import java.util.Collections; ArrayList<String> list = new ArrayList<>(); Collections.sort(list); What the import statement does: ─ Tells the compiler: "when you see ArrayList, look in java.util" ─ Does NOT copy any code or load any class at compile time ─ Does NOT affect bytecode or runtime performance ─ Does NOT make the JAR file larger ─ Is purely a compile-time name-resolution instruction
1 — Single-Type Import (Specific Import)
A single-type import imports exactly one class. This is the recommended style — it makes every dependency explicit and readable at a glance.
1// File: SingleTypeImportDemo.java
2
3package com.devstackflow.demo;
4
5// Each import names exactly one class
6import java.util.ArrayList;
7import java.util.HashMap;
8import java.util.List;
9import java.util.Map;
10import java.util.Collections;
11import java.time.LocalDate;
12import java.time.format.DateTimeFormatter;
13import java.math.BigDecimal;
14
15public class SingleTypeImportDemo {
16
17 public static void main(String[] args) {
18
19 // All imported classes available by simple name
20 List<String> cities = new ArrayList<>();
21 cities.add("Mumbai");
22 cities.add("Delhi");
23 cities.add("Bengaluru");
24 Collections.sort(cities);
25 System.out.println("Cities : " + cities);
26
27 Map<String, Integer> population = new HashMap<>();
28 population.put("Mumbai", 20_000_000);
29 population.put("Delhi", 32_000_000);
30 population.put("Bengaluru", 13_000_000);
31 System.out.println("Population : " + population);
32
33 LocalDate today = LocalDate.now();
34 DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MMM-yyyy");
35 System.out.println("Today : " + today.format(fmt));
36
37 BigDecimal price = new BigDecimal("4999.99");
38 System.out.println("Price : Rs." + price);
39 }
40}Output:
Cities : [Bengaluru, Delhi, Mumbai]
Population : {Mumbai=20000000, Delhi=32000000, Bengaluru=13000000}
Today : 15-Jan-2024
Price : Rs.4999.99
Specific imports are preferred in professional code because any developer reading the file can immediately see which classes are used — without having to look up what * pulled in.
2 — Wildcard Import
A wildcard import — import package.*; — imports all public classes in a package with one statement. It does not import sub-packages or package-private classes.
1// File: WildcardImportDemo.java
2
3package com.devstackflow.demo;
4
5// Wildcard — imports all public classes in java.util
6import java.util.*;
7
8// Sub-packages are NOT included — must import separately
9import java.util.stream.*;
10import java.util.concurrent.*;
11
12public class WildcardImportDemo {
13
14 public static void main(String[] args) {
15
16 // All java.util classes available
17 List<String> names = new ArrayList<>(List.of("Priya", "Rohan", "Sneha"));
18 Map<String, Integer> scores = new HashMap<>();
19 scores.put("Priya", 95);
20 scores.put("Rohan", 88);
21 scores.put("Sneha", 92);
22
23 Optional<String> topScorer = scores.entrySet().stream()
24 .max(Map.Entry.comparingByValue())
25 .map(Map.Entry::getKey);
26
27 System.out.println("Names : " + names);
28 System.out.println("Scores : " + scores);
29 System.out.println("Top scorer : " + topScorer.orElse("none"));
30
31 System.out.println();
32
33 // java.util.stream was imported separately — not included in java.util.*
34 Stream<String> upperNames = names.stream()
35 .map(String::toUpperCase);
36 System.out.println("Uppercased : ");
37 upperNames.forEach(n -> System.out.println(" " + n));
38
39 System.out.println();
40
41 // java.util.concurrent was imported separately
42 ExecutorService executor = Executors.newFixedThreadPool(2);
43 executor.submit(() -> System.out.println("Task from thread pool"));
44 executor.shutdown();
45 }
46}Output:
Names : [Priya, Rohan, Sneha]
Scores : {Priya=95, Rohan=88, Sneha=92}
Top scorer : Priya
Uppercased :
PRIYA
ROHAN
SNEHA
Task from thread pool
The wildcard * is convenient for exploration but most style guides — Google Java Style Guide, Oracle Coding Conventions — prefer specific imports. IDEs like IntelliJ IDEA automatically expand wildcards to specific imports on save.
Specific Import vs Wildcard Import — Comparison Table
| Aspect | Specific Import import java.util.ArrayList | Wildcard Import import java.util.* |
|---|---|---|
| Readability | High — every dependency visible at top | Lower — unclear which classes are used |
| Compile time | No measurable difference | No measurable difference |
| Runtime performance | Identical — both are compile-time only | Identical |
| Risk of name conflict | Low — explicit class chosen | Higher — two packages may contribute same name |
| Sub-packages included | N/A | No — java.util.* does not include java.util.stream.* |
| IDE behaviour | Preferred — auto-organised by IDE | IDE warns or auto-expands to specific |
| Style guides | Recommended | Discouraged in production code |
| When appropriate | Always in production code | Quick prototyping, exam code |
3 — Static Import
import static imports a specific static member — field or method — from a class so it can be used without the class name prefix.
1// File: StaticImportDemo.java
2
3package com.devstackflow.demo;
4
5// Import specific static members
6import static java.lang.Math.PI;
7import static java.lang.Math.sqrt;
8import static java.lang.Math.pow;
9import static java.lang.Math.abs;
10
11// Import all static members of a class
12import static java.util.Collections.sort;
13import static java.util.Collections.reverse;
14import static java.util.Collections.unmodifiableList;
15
16// Import constant from custom class
17import static com.devstackflow.demo.AppConstants.MAX_RETRIES;
18import static com.devstackflow.demo.AppConstants.DEFAULT_TIMEOUT;
19
20import java.util.ArrayList;
21import java.util.Arrays;
22import java.util.List;
23
24class AppConstants {
25 public static final int MAX_RETRIES = 3;
26 public static final long DEFAULT_TIMEOUT = 5000L;
27 public static final String APP_NAME = "DevStackFlow";
28}
29
30public class StaticImportDemo {
31
32 public static void main(String[] args) {
33
34 // Math methods without "Math." prefix
35 double radius = 7.0;
36 double area = PI * pow(radius, 2);
37 double perimeter = 2 * PI * radius;
38 double diagonal = sqrt(pow(5, 2) + pow(12, 2));
39
40 System.out.printf("Circle radius : %.1f%n", radius);
41 System.out.printf("Circle area : %.2f%n", area);
42 System.out.printf("Circumference : %.2f%n", perimeter);
43 System.out.printf("3-4-5 diagonal : %.2f%n", diagonal);
44 System.out.printf("abs(-42) : %d%n", abs(-42));
45
46 System.out.println();
47
48 // Collections methods without "Collections." prefix
49 List<String> products = new ArrayList<>(
50 Arrays.asList("Laptop", "Mouse", "Keyboard", "Monitor", "Headphones"));
51
52 System.out.println("Before sort : " + products);
53 sort(products);
54 System.out.println("After sort : " + products);
55 reverse(products);
56 System.out.println("After reverse : " + products);
57
58 List<String> immutable = unmodifiableList(products);
59 System.out.println("Immutable list : " + immutable);
60
61 System.out.println();
62
63 // Custom constants without class prefix
64 System.out.println("Max retries : " + MAX_RETRIES);
65 System.out.println("Default timeout : " + DEFAULT_TIMEOUT + "ms");
66 }
67}Output:
Circle radius : 7.0
Circle area : 153.94
Circumference : 43.98
3-4-5 diagonal : 13.00
abs(-42) : 42
Before sort : [Laptop, Mouse, Keyboard, Monitor, Headphones]
After sort : [Headphones, Keyboard, Laptop, Monitor, Mouse]
After reverse : [Mouse, Monitor, Laptop, Keyboard, Headphones]
Immutable list : [Mouse, Monitor, Laptop, Keyboard, Headphones]
Max retries : 3
Default timeout : 5000ms
Static import is most valuable for: Math methods in mathematical code, Assert methods in unit tests (assertEquals, assertTrue), and constants across the codebase. Avoid it when it makes code less clear — sort(list) is readable, but importing unrelated constants with the same name from multiple classes creates confusion.
4 — java.lang — The Auto-Imported Package
java.lang is the only package automatically imported in every Java file. You never need to write import java.lang.String or import java.lang.System.
1// File: AutoImportDemo.java
2
3package com.devstackflow.demo;
4
5// No imports needed for any java.lang class
6// All of the following are automatically available:
7
8public class AutoImportDemo {
9
10 public static void main(String[] args) {
11
12 // java.lang.String — no import needed
13 String message = "Hello, DevStackFlow!";
14 System.out.println(message.toUpperCase());
15
16 // java.lang.System — no import needed
17 System.out.println("Java version: " + System.getProperty("java.version"));
18
19 // java.lang.Math — no import needed
20 System.out.println("Max of 5,9 : " + Math.max(5, 9));
21 System.out.println("PI : " + Math.PI);
22
23 // java.lang.Integer — no import needed
24 int parsed = Integer.parseInt("42");
25 System.out.println("Parsed : " + parsed);
26 System.out.println("Max int : " + Integer.MAX_VALUE);
27
28 // java.lang.StringBuilder — no import needed
29 StringBuilder sb = new StringBuilder("Hello");
30 sb.append(", World");
31 System.out.println("SB result : " + sb);
32
33 // java.lang.Thread — no import needed
34 System.out.println("Thread : " + Thread.currentThread().getName());
35
36 // java.lang.Object — root of all classes — no import needed
37 Object obj = new Object();
38 System.out.println("Object hash: " + obj.hashCode());
39 }
40}Output:
HELLO, DEVSTACKFLOW!
Java version: 17.0.9
Max of 5,9 : 9
PI : 3.141592653589793
Parsed : 42
Max int : 2147483647
SB result : Hello, World
Thread : main
Object hash: 1173230247
5 — Handling Naming Conflicts
When two packages you need both have a class with the same name, you can only import one by simple name. The other must be used with its fully qualified class name.
1// File: NamingConflictDemo.java
2
3package com.devstackflow.demo;
4
5// Both java.util and java.sql have a class named "Date"
6import java.util.Date;
7// import java.sql.Date; ← cannot import both — same simple name
8
9import java.sql.Connection;
10import java.sql.PreparedStatement;
11
12public class NamingConflictDemo {
13
14 public static void main(String[] args) {
15
16 // java.util.Date — can use simple name because it was imported
17 Date utilDate = new Date();
18 System.out.println("java.util.Date : " + utilDate);
19
20 // java.sql.Date — must use FQCN because it conflicts with the import above
21 java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());
22 System.out.println("java.sql.Date : " + sqlDate);
23
24 System.out.println();
25
26 // Another common conflict — java.util.List and java.awt.List
27 java.util.List<String> utilList = new java.util.ArrayList<>();
28 utilList.add("item1");
29 System.out.println("java.util.List : " + utilList);
30 // java.awt.List — if needed, use: java.awt.List awtList = new java.awt.List();
31
32 System.out.println();
33
34 // Best approach when conflict is unavoidable:
35 // Import the one you use most, FQCN for the other
36 // OR use FQCNs for both to make the code unambiguous
37 System.out.println("Conflict resolution: import most-used, FQCN for the rest");
38 }
39}Output:
java.util.Date : Mon Jan 15 10:30:00 IST 2024
java.sql.Date : 2024-01-15
java.util.List : [item1]
Conflict resolution: import most-used, FQCN for the rest
6 — Import Ordering and Organisation
The standard import order — enforced by tools like Google Java Style Guide, Checkstyle, and IDE formatters — keeps imports consistent across a team.
1// File: ImportOrderDemo.java
2
3package com.devstackflow.demo;
4
5// ── Block 1: java.* imports ──────────────────────────
6import java.math.BigDecimal;
7import java.time.LocalDate;
8import java.time.LocalDateTime;
9import java.util.ArrayList;
10import java.util.HashMap;
11import java.util.List;
12import java.util.Map;
13
14// ── Block 2: javax.* imports ─────────────────────────
15import javax.crypto.Cipher;
16
17// ── Block 3: Third-party library imports ─────────────
18// import org.springframework.stereotype.Service;
19// import com.fasterxml.jackson.databind.ObjectMapper;
20
21// ── Block 4: Internal project imports (same project) ─
22// import com.devstackflow.model.Student;
23// import com.devstackflow.service.StudentService;
24
25// ── Block 5: Static imports (at the end) ─────────────
26import static java.lang.Math.PI;
27import static java.util.Collections.sort;
28
29public class ImportOrderDemo {
30
31 public static void main(String[] args) {
32
33 // All imports available by simple name
34 List<String> cities = new ArrayList<>();
35 cities.add("Mumbai");
36 cities.add("Delhi");
37 cities.add("Pune");
38 sort(cities); // static import
39
40 Map<String, BigDecimal> prices = new HashMap<>();
41 prices.put("Laptop", new BigDecimal("45999.00"));
42 prices.put("Monitor", new BigDecimal("18500.00"));
43
44 LocalDate orderDate = LocalDate.now();
45 LocalDateTime timestamp = LocalDateTime.now();
46
47 System.out.println("Cities : " + cities);
48 System.out.println("Prices : " + prices);
49 System.out.println("Order date: " + orderDate);
50 System.out.println("PI : " + PI);
51 }
52}Output:
Cities : [Delhi, Mumbai, Pune]
Prices : {Laptop=45999.00, Monitor=18500.00}
Order date: 2024-01-15
PI : 3.141592653589793
Most IDEs format imports automatically. In IntelliJ IDEA: Code → Optimize Imports removes unused imports and organises the rest. In VS Code with the Java extension: imports are managed on save.
Real-World Example — Notification Service With Multiple Import Types
The Business Problem
A notification service at a company like Swiggy or Zomato sends order updates via SMS, email, and push notifications. It uses classes from java.util, java.time, java.math, and the project's own packages — demonstrating specific imports, static imports, and FQCN usage when a conflict arises in a realistic setting.
1// File: com/swiggy/notification/model/NotificationEvent.java
2package com.swiggy.notification.model;
3
4import java.time.LocalDateTime;
5import java.time.format.DateTimeFormatter;
6
7public class NotificationEvent {
8
9 public enum Channel { SMS, EMAIL, PUSH }
10 public enum Priority { LOW, NORMAL, HIGH, CRITICAL }
11
12 private final String eventId;
13 private final String userId;
14 private final String orderId;
15 private final String message;
16 private final Channel channel;
17 private final Priority priority;
18 private final LocalDateTime createdAt;
19
20 public NotificationEvent(String eventId, String userId,
21 String orderId, String message,
22 Channel channel, Priority priority) {
23 this.eventId = eventId;
24 this.userId = userId;
25 this.orderId = orderId;
26 this.message = message;
27 this.channel = channel;
28 this.priority = priority;
29 this.createdAt = LocalDateTime.now();
30 }
31
32 private static final DateTimeFormatter FMT =
33 DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss");
34
35 public String getEventId() { return eventId; }
36 public String getUserId() { return userId; }
37 public String getOrderId() { return orderId; }
38 public String getMessage() { return message; }
39 public Channel getChannel() { return channel; }
40 public Priority getPriority(){ return priority; }
41
42 @Override
43 public String toString() {
44 return String.format("[%s] User:%s | Order:%s | %s | %s | %s | %s",
45 eventId, userId, orderId, channel, priority,
46 createdAt.format(FMT), message);
47 }
48}1// File: com/swiggy/notification/util/EventIdGenerator.java
2package com.swiggy.notification.util;
3
4import java.util.concurrent.atomic.AtomicLong;
5
6public class EventIdGenerator {
7
8 private static final AtomicLong counter = new AtomicLong(1);
9
10 public static String generate(String prefix) {
11 return prefix + "-EVT-" + String.format("%05d", counter.getAndIncrement());
12 }
13}1// File: com/swiggy/notification/service/NotificationService.java
2package com.swiggy.notification.service;
3
4// java.* specific imports
5import java.math.BigDecimal;
6import java.time.LocalDateTime;
7import java.time.format.DateTimeFormatter;
8import java.util.ArrayList;
9import java.util.Comparator;
10import java.util.List;
11import java.util.Map;
12import java.util.stream.Collectors;
13
14// Internal project imports
15import com.swiggy.notification.model.NotificationEvent;
16import com.swiggy.notification.model.NotificationEvent.Channel;
17import com.swiggy.notification.model.NotificationEvent.Priority;
18import com.swiggy.notification.util.EventIdGenerator;
19
20// Static imports
21import static java.lang.String.format;
22import static java.util.Collections.unmodifiableList;
23
24public class NotificationService {
25
26 private final List<NotificationEvent> eventLog = new ArrayList<>();
27
28 public NotificationEvent send(String userId, String orderId,
29 String message,
30 Channel channel, Priority priority) {
31
32 String id = EventIdGenerator.generate(channel.name());
33 NotificationEvent event = new NotificationEvent(
34 id, userId, orderId, message, channel, priority);
35 eventLog.add(event);
36
37 // Static import of String.format used as 'format'
38 String log = format(" [SENT] %-12s → %s | %s",
39 channel, userId, message);
40 System.out.println(log);
41
42 return event;
43 }
44
45 public List<NotificationEvent> getByChannel(Channel channel) {
46 return eventLog.stream()
47 .filter(e -> e.getChannel() == channel)
48 .collect(Collectors.toList());
49 }
50
51 public List<NotificationEvent> getByPriority(Priority priority) {
52 return eventLog.stream()
53 .filter(e -> e.getPriority() == priority)
54 .sorted(Comparator.comparing(NotificationEvent::getEventId))
55 .collect(Collectors.toList());
56 }
57
58 public Map<Channel, Long> getChannelStats() {
59 return eventLog.stream()
60 .collect(Collectors.groupingBy(
61 NotificationEvent::getChannel,
62 Collectors.counting()));
63 }
64
65 public List<NotificationEvent> getAllEvents() {
66 return unmodifiableList(eventLog); // static import
67 }
68}1// File: com/swiggy/NotificationApp.java
2package com.swiggy;
3
4// Specific imports — each dependency is explicit
5import com.swiggy.notification.model.NotificationEvent;
6import com.swiggy.notification.model.NotificationEvent.Channel;
7import com.swiggy.notification.model.NotificationEvent.Priority;
8import com.swiggy.notification.service.NotificationService;
9
10import java.util.List;
11import java.util.Map;
12
13public class NotificationApp {
14
15 public static void main(String[] args) {
16
17 System.out.println("╔══════════════════════════════════════════╗");
18 System.out.println("║ SWIGGY NOTIFICATION SERVICE DEMO ║");
19 System.out.println("╚══════════════════════════════════════════╝\n");
20
21 NotificationService service = new NotificationService();
22
23 System.out.println("Sending notifications:");
24 System.out.println("─".repeat(65));
25
26 service.send("USR-101", "ORD-001", "Order placed! Preparing now.",
27 Channel.SMS, Priority.NORMAL);
28 service.send("USR-102", "ORD-002", "Your food is being prepared.",
29 Channel.PUSH, Priority.NORMAL);
30 service.send("USR-101", "ORD-001", "Rider assigned. Arriving in 25 mins.",
31 Channel.SMS, Priority.HIGH);
32 service.send("USR-103", "ORD-003", "Payment failed. Please retry.",
33 Channel.EMAIL, Priority.CRITICAL);
34 service.send("USR-102", "ORD-002", "Order delivered!",
35 Channel.PUSH, Priority.NORMAL);
36 service.send("USR-103", "ORD-003", "Order cancelled. Refund initiated.",
37 Channel.SMS, Priority.HIGH);
38
39 System.out.println();
40
41 // Channel statistics
42 System.out.println("Channel stats:");
43 Map<Channel, Long> stats = service.getChannelStats();
44 stats.forEach((ch, count) ->
45 System.out.printf(" %-8s : %d event(s)%n", ch, count));
46
47 System.out.println();
48
49 // All CRITICAL priority events
50 System.out.println("Critical events:");
51 List<NotificationEvent> critical = service.getByPriority(Priority.CRITICAL);
52 critical.forEach(e -> System.out.println(" " + e));
53
54 System.out.println();
55
56 // All SMS events
57 System.out.println("SMS events:");
58 service.getByChannel(Channel.SMS)
59 .forEach(e -> System.out.println(" " + e));
60 }
61}Output:
╔══════════════════════════════════════════╗
║ SWIGGY NOTIFICATION SERVICE DEMO ║
╚══════════════════════════════════════════╝
Sending notifications:
─────────────────────────────────────────────────────────────────
[SENT] SMS → USR-101 | Order placed! Preparing now.
[SENT] PUSH → USR-102 | Your food is being prepared.
[SENT] SMS → USR-101 | Rider assigned. Arriving in 25 mins.
[SENT] EMAIL → USR-103 | Payment failed. Please retry.
[SENT] PUSH → USR-102 | Order delivered!
[SENT] SMS → USR-103 | Order cancelled. Refund initiated.
Channel stats:
SMS : 3 event(s)
PUSH : 2 event(s)
EMAIL : 1 event(s)
Critical events:
[EMAIL-EVT-00004] User:USR-103 | Order:ORD-003 | EMAIL | CRITICAL | 15-Jan-2024 10:30:04 | Payment failed. Please retry.
SMS events:
[SMS-EVT-00001] User:USR-101 | Order:ORD-001 | SMS | NORMAL | 15-Jan-2024 10:30:01 | Order placed! Preparing now.
[SMS-EVT-00003] User:USR-101 | Order:ORD-001 | SMS | HIGH | 15-Jan-2024 10:30:03 | Rider assigned. Arriving in 25 mins.
[SMS-EVT-00006] User:USR-103 | Order:ORD-003 | SMS | HIGH | 15-Jan-2024 10:30:06 | Order cancelled. Refund initiated.
Every import is specific and intentional. NotificationEvent.Channel and NotificationEvent.Priority are imported as nested types. format and unmodifiableList are statically imported for clean readability in the service. No wildcard anywhere.
Best Practices
Use specific imports over wildcards in production code. A specific import on every dependency makes the file self-documenting — any reader instantly knows which external types are used. Wildcards save typing but hide dependencies. Every major style guide — Google, Oracle, Spring — mandates specific imports.
Let the IDE manage imports. Do not type import statements manually. In IntelliJ IDEA, Alt+Enter on a class name adds the import automatically. Ctrl+Alt+O (or Cmd+Alt+O on macOS) removes unused imports and organises the rest. In VS Code, the Java extension does the same on save. Manual import management wastes time and introduces errors.
Reserve static imports for well-understood constants and utility methods. import static java.lang.Math.PI and import static org.junit.jupiter.api.Assertions.assertEquals are idiomatic and universally understood. Avoid statically importing methods whose origin is not obvious — sort(list) is clear from context, but process(data) imported from an obscure utility class makes the code opaque.
Remove unused imports. Unused imports are noise — they suggest dependencies that do not exist. They trigger warnings in tools like Checkstyle, SonarQube, and most IDEs. Most CI pipelines fail on unused import warnings. Keep imports clean — one import per class actually used.
Common Mistakes
Mistake 1 — Wildcard Does Not Cover Sub-packages
1import java.util.*; // imports ArrayList, HashMap, Optional, etc.
2// Does NOT import java.util.stream.Stream
3// Does NOT import java.util.concurrent.ExecutorService
4
5Stream<String> stream = // compile error: cannot find symbol Stream
6
7// Fix — import sub-package separately
8import java.util.stream.Stream;
9import java.util.concurrent.ExecutorService;Mistake 2 — Importing a Class That Does Not Need Importing
1// java.lang is auto-imported — these are redundant
2import java.lang.String; // redundant — String is always available
3import java.lang.System; // redundant — System is always available
4import java.lang.Math; // redundant — Math is always available
5import java.lang.Integer; // redundant — Integer is always available
6
7// IDEs mark all java.lang imports as "redundant import"
8// Style checkers like Checkstyle flag them as violationsMistake 3 — Ambiguous Import When Two Packages Have Same Class Name
1import java.util.Date;
2import java.sql.Date; // compile error: Date is already defined
3
4// Fix — import only one, use FQCN for the other
5import java.util.Date;
6
7public class Example {
8 Date utilDate = new Date(); // java.util.Date
9 java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis()); // FQCN
10}Mistake 4 — Placing Import Before Package Declaration
1import java.util.List; // compile error: import before package declaration
2
3package com.devstackflow; // package must be the first non-comment statement
4
5// Correct order:
6package com.devstackflow;
7import java.util.List;
8public class Example { }Interview Questions
Q1. What does the import statement do in Java?
The import statement is a compile-time instruction that tells the compiler how to resolve a short class name to its fully qualified name. Without it, every class outside java.lang must be referenced by its full package path — java.util.ArrayList instead of ArrayList. The import does not load any code, does not affect the compiled bytecode, does not make the program slower, and does not increase JAR size. It purely enables short-name usage in source code.
Q2. What is the difference between a specific import and a wildcard import?
A specific import — import java.util.ArrayList — imports exactly one named class. A wildcard import — import java.util.* — imports all public classes directly in the specified package, but not sub-packages or package-private classes. Both produce identical compiled bytecode — the compiler resolves which classes are actually used regardless of how many the wildcard might cover. The practical difference is readability and conflict risk: specific imports make dependencies explicit and reduce the chance of name collision.
Q3. What is a static import and when should you use it?
import static imports a static member — field or method — from a class, allowing it to be used without the class name prefix. import static java.lang.Math.PI lets you write PI instead of Math.PI. Static imports are most appropriate for Math constants and methods in mathematical code, Assert methods in JUnit tests (assertEquals, assertTrue), and widely-used constants from your own codebase. Avoid them when the imported name's origin is not obvious from context — clarity always beats brevity.
Q4. Which package is automatically imported in every Java file?
java.lang is the only package automatically imported without any explicit import statement. This provides String, System, Math, Integer, Long, Double, Boolean, Character, StringBuilder, StringBuffer, Thread, Object, Exception, RuntimeException, and all other core language classes without any declaration. All other packages — including java.util, java.io, and java.time — require explicit imports.
Q5. What happens when two imported packages both contain a class with the same name?
A naming conflict occurs. If you write import java.util.Date; import java.sql.Date;, the compiler reports an error — two imports resolve to the same simple name Date. The solution is to import only the more frequently used class and reference the other by its FQCN wherever it appears. Alternatively, remove both imports and use FQCNs for both throughout the file, which makes the distinction explicit at every usage point.
Q6. Does a wildcard import from java.util also import java.util.stream?
No. A wildcard import only covers the classes directly in the named package — it does not extend to sub-packages. import java.util.* imports ArrayList, HashMap, Collections, Optional, and every other public class directly in java.util, but it does not import java.util.stream.Stream, java.util.stream.Collectors, java.util.concurrent.ExecutorService, or any other class in a sub-package. Each sub-package requires its own import statement.
FAQs
Does the order of import statements matter?
The compiler does not care about import order — it processes all imports regardless of sequence. However, teams enforce a standard ordering through style guides and tools. The typical convention: java.* imports first, then javax.*, then third-party libraries, then internal project imports, with static imports last. IDEs auto-sort imports according to configured rules. Consistent ordering reduces unnecessary diffs in version control when two developers independently add imports to the same file.
Can you import a class from the default package?
No. Classes in the default (unnamed) package cannot be imported by classes in named packages. The import keyword requires a fully qualified name with at least one dot separator, which the default package cannot provide. This is one of the fundamental reasons why the default package must be avoided in any project where code needs to be reused or imported.
What is an unused import and why does it matter?
An unused import is an import statement for a class that is not referenced anywhere in the file. The compiler ignores it — it produces no error and no effect on the program. However, unused imports are considered code smell. They mislead readers into thinking a dependency exists when it does not, they trigger warnings from Checkstyle, PMD, and SpotBugs, and they cause test failures on CI pipelines configured to treat warnings as errors. IDEs show them in grey and provide one-click removal.
Can two classes in the same package import each other?
Classes in the same package do not need to import each other at all — they are always mutually visible without any import. If Order.java and OrderItem.java are both in com.myapp.order, either can use the other by simple name with no import statement. This is one of the practical benefits of grouping related classes into the same package.
Is there a performance difference between importing ten specific classes and using a wildcard that covers them all?
No measurable difference at runtime. Both approaches result in exactly the same compiled bytecode — the import statement is erased during compilation. The only difference is at compile time, where the compiler must scan for classes matching the wildcard, which is slightly slower for very large packages with hundreds of classes. In practice this is completely negligible. The choice between specific and wildcard imports is purely a readability and maintainability decision.
Summary
The import statement is a compile-time shortcut — it resolves simple class names to their fully qualified package paths so that you can write ArrayList instead of java.util.ArrayList throughout the file. It has zero effect on the compiled bytecode, the JAR size, or runtime performance.
Three forms: specific import for one class, wildcard for all public classes in a package (but never sub-packages), and static import for static members. java.lang is the sole automatically imported package.
The practice every professional Java team follows: specific imports always, wildcards never in production code, static imports only for well-understood utilities, and IDE import management to keep things clean and ordered.
What to Read Next
Take a closer look at how access modifiers control visibility.