skip to content

Import Declarations

Single-type imports, wildcard imports, and the resolution order when two packages offer the same simple name — same-package and single-type imports win over wildcards. Interviewers use the java.util.List versus java.awt.List clash to make the rule concrete.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

6

Why don't you need to import String, Integer, or Object, and what makes the java.lang package special?

level: juniorimportance: must knowfreq 58%

answer

  1. Every file implicitly does `import java.lang.*;`
  2. java.lang = Object, String, wrappers, System, exceptions
  3. It's wildcard-strength → can be shadowed by same-package/single import
  4. Sub-packages (java.lang.reflect) are NOT auto-imported
  5. Don't redundantly import java.lang types

basics

~10 s

Every Java file automatically imports the java.lang package, where String, Integer, Object, System, and similar core types live. So you can use them by simple name without writing any import.

solid answer

~40 s

The Java compiler implicitly performs `import java.lang.*;` in every compilation unit. `java.lang` holds the foundational types the language itself depends on — `Object`, `String`, the primitive wrappers (`Integer`, `Boolean`…), `System`, `Math`, `Thread`, `Throwable`/`Exception`, and so on — so they're always available by simple name with no explicit import. This is the only package auto-imported (besides types in your own package being visible). It's a wildcard-strength import, so it can be **shadowed**: if you declare your own class named `String` in the current package (or import one by name), your `String` wins over `java.lang.String` because same-package/single-type imports out-rank the implicit on-demand `java.lang.*`. Sub-packages like `java.lang.reflect` are NOT auto-imported — only `java.lang` itself.

go deeper

for a junior

Knows core types like String/Object/System need no import because java.lang is implicitly available.

for a middle

Explains it's an implicit java.lang.* wildcard, lists representative members, and knows sub-packages aren't auto-imported.

for a senior

Adds that the implicit import is wildcard-strength and thus shadowable by same-package/single-type imports, with the String-shadowing example.

for a principal

Connects the rule to naming conventions and code-review standards (never shadow core types), and explains why the language must keep these types always in scope (literals, autoboxing, exception model).

## The implicit import Every Java source file behaves as if it begins with: ```java import java.lang.*; ``` This is added automatically by the compiler. That's why you can write `String s = "hi";` or `System.out.println(...)` or `new Object()` with no import line — those types live in **`java.lang`**. ## What's in java.lang `java.lang` is the package of types so fundamental that the language can't function without them: - `Object` — the root of every class hierarchy. - `String` — string literals are `String` instances. - Primitive **wrapper** classes: `Integer`, `Long`, `Double`, `Boolean`, `Character`, etc. (autoboxing depends on these). - `System`, `Math`, `Thread`, `Runnable`. - The throwable hierarchy: `Throwable`, `Exception`, `RuntimeException`, `Error`. - `Class`, `Enum`, `Comparable`, `Iterable`, `CharSequence`. Because the language semantics (string literals, exceptions, the class hierarchy, autoboxing) reference these directly, they must always be in scope. ## It's a wildcard — so it can be shadowed The implicit `java.lang.*` is an **on-demand (wildcard)** import, which is the *weakest* form in the precedence ladder. Therefore: - A type in your **own package** with the same simple name shadows it. - A **single-type import** with the same simple name shadows it. Example (a terrible idea, but legal): ```java package com.example; class String { } // your own String class Use { String s; // refers to com.example.String, NOT java.lang.String! } ``` Here your `String` (same package) out-ranks the implicit `java.lang.String`. This is why shadowing core names is strongly discouraged. ## Only java.lang itself — not its sub-packages Auto-import covers exactly the `java.lang` package. **Sub-packages are separate packages and are NOT auto-imported:** - `java.lang.reflect.Method` → needs `import java.lang.reflect.Method;` - `java.lang.annotation.Retention` → needs an explicit import. This mirrors the general rule that wildcard imports never recurse into sub-packages. ## Practical takeaways 1. Never import `java.lang` types explicitly — it's redundant (some linters flag it). 2. Don't name your own classes after `java.lang` types; you'll create confusing shadowing. 3. Remember `java.lang.reflect`, `java.lang.annotation`, etc. **do** need imports.

  • Do you need to import java.lang.reflect.Method?
    Yes. Only the `java.lang` package itself is auto-imported; sub-packages like `java.lang.reflect` are separate packages and require an explicit import.
  • What happens if you declare a class named String in your own package?
    Your `String` shadows `java.lang.String` within that package, because same-package types out-rank the implicit wildcard `java.lang.*`. It compiles but is extremely confusing and should be avoided.

saying these in an interview costs you the question

  • Thinking you must import String/Object/System
  • Believing java.lang.reflect is auto-imported too
  • Claiming the implicit import can't be shadowed
  • Saying every java.* package is auto-imported

context

open as a page

What is the difference between a single-type import and a wildcard (on-demand) import in Java, and when would you prefer each?

level: juniorimportance: must knowfreq 70%

basics

~10 s

A single-type import names one class, like import java.util.List;. A wildcard import, like import java.util.*;, lets you use any class from that package. Single imports are clearer and usually preferred.

open as a page

When a simple type name could be resolved several ways, what is Java's precedence among same-package types, single-type imports, and wildcard imports?

level: middleimportance: should knowfreq 48%

basics

~20 s

Java looks for a name in this order of strength: a type in the same package or one you imported by name beats a wildcard import. So a single-type import always wins over *, and a wildcard never overrides an explicitly named type.

open as a page

Two types you need share the same simple name (e.g. java.util.Date and java.sql.Date). How do you use both in one source file?

level: middleimportance: should knowfreq 55%

basics

~20 s

You can only import one of them by name. Import one (say import java.util.Date;) and refer to the other by its full name, java.sql.Date, everywhere you use it. There's no syntax to rename an import in Java.

open as a page

What is a static import, how does it differ from an ordinary import, and what are its pitfalls?

level: middleimportance: should knowfreq 50%

basics

~20 s

A static import brings a class's static members (methods or fields) into scope so you can call them without the class name — e.g. import static java.lang.Math.PI; lets you write PI instead of Math.PI. Ordinary imports bring in types.

open as a page

In the Java Platform Module System (JPMS), why isn't an import enough to use a type from another module, and how do imports relate to module readability and exported packages?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

An import only tells the compiler how to read a short name. Under the module system (since Java 9), the type's package must also be exported by its module and your module must require that module. Without those, the import fails even if the class exists.

open as a page