Compare the single-member static import with the static wildcard import (import static Foo.*). What does each bring in, and when would you prefer one over the other?
answer
- single = one named member (all its overloads)
- wildcard = all static members
- explicit beats wildcard in resolution
- wildcard imports members not nested types
- default explicit; wildcard for dense use (tests)
basics
~20 sSingle-member: import static Foo.bar; brings in just bar. Wildcard: import static Foo.*; brings in all of Foo's accessible static members at once. Prefer naming the few members you use; use the wildcard only when you really use many.
solid answer
~50 sThere are two syntactic forms. The single-member form, import static java.lang.Math.max;, brings exactly one named static member into scope. The wildcard form, import static java.lang.Math.*;, brings in every accessible static member of the type (all static fields and methods, including overloads). Functionally either lets you reference those members unqualified. The trade-off is explicitness vs brevity: single-member imports document precisely which names came from where, which keeps readers and tools oriented and reduces ambiguity risk; the wildcard is terser but pulls in everything, making it more likely two wildcard imports contribute a clashing simple name and obscuring a name's origin. The pragmatic rule: list members explicitly by default, and reserve the wildcard for cases where you genuinely use many static members of one type — classically a test class importing most of a JUnit/Hamcrest assertion API. Note the wildcard imports members, not nested types.
go deeper
Knows there are two forms: naming one member vs using * to get everything static from a class.
Explains that single-member imports a name (with all its overloads), wildcard imports all accessible static members, and gives the explicit-by-default guideline.
Adds the resolution precedence (local/inherited > explicit > wildcard), the members-not-nested-types nuance, and the test-DSL exception where wildcards are idiomatic.
Sets a team policy weighing self-documentation and clash risk against brevity, and connects it to tooling (IDE auto-import settings, lint rules).
## Setup: a static member A **static member** belongs to a class, not an instance: e.g. the method `Math.max`, the field `Math.PI`, the constant `Integer.MAX_VALUE`. A **static import** lets you write that member's **simple name** (e.g. `max`) without the `ClassName.` prefix. There are two ways to write it. ## Form 1 — single-member (explicit) static import ```java import static java.lang.Math.max; import static java.lang.Math.min; import static java.lang.Math.PI; ``` Each line names exactly **one** member by its simple name. Importing `max` brings in *all overloads* named `max` (e.g. the `int`, `long`, `double` versions) — a static import targets a **name**, not a single signature. It does **not** bring in `min`, `PI`, or anything else; you import those separately. ## Form 2 — wildcard (on-demand) static import ```java import static java.lang.Math.*; ``` The `*` brings in **all accessible static members** of `Math` in one line: every static method and field you're allowed to see. After this you can write `max(...)`, `min(...)`, `sqrt(...)`, `PI`, etc., all unqualified. Important nuance: the static `*` imports **static members**, not **nested types**. To bring a nested *type* into scope by simple name you use a *regular* `import Outer.Nested;` (or its wildcard), not a static import. ## How the compiler resolves an unqualified name When the compiler sees a bare name like `max(...)`, it searches a precedence chain: members declared in the current class and its supertypes first, then single-member (explicit) imports, and finally on-demand (wildcard) imports last. Explicit beats wildcard, and local/inherited members beat both. This precedence is exactly why wildcards are riskier (see ambiguity below). ## The trade-off — when to prefer which - **Single-member (default choice):** self-documenting (the import list is a precise inventory of borrowed names), minimizes clashes, and keeps a name's origin discoverable. Cost: more import lines. - **Wildcard (reserve for high-density use):** terse when you use *many* members of one type. Cost: a reader can't tell from the imports which names you actually use or where a given simple name comes from; adding two static wildcards raises clash risk. A widely-followed guideline (and many team style guides) is: **import members explicitly; use a static wildcard only when you use a large fraction of a class's static API** — the canonical example being a test class doing `import static org.junit.jupiter.api.Assertions.*;` and `import static org.hamcrest.Matchers.*;` so that `assertThat(x, is(3))` reads as a fluent DSL. ## Ambiguity preview If two **wildcard** static imports each expose a static member with the same simple name, an *unqualified* use is a **compile error** for ambiguity (you must qualify or switch to an explicit import). A single-member import is unambiguous for that name and will even shadow a wildcard-provided one. This is the core reason explicit imports are safer (covered fully in the ambiguity question).
- If you do import static Math.max, do you get all overloads of max or just one?All overloads named max. A static import targets the member name, so every method with that name and any visible field with that name is in scope; overload resolution then picks the right signature at the call site.
- Does import static com.example.Outer.* bring the nested class Outer.Inner into scope?No. The static wildcard imports static members (fields/methods), not nested types. To use Inner by simple name you need a regular import com.example.Outer.Inner;.
saying these in an interview costs you the question
- Thinking single-member import brings in only one overload of an overloaded method
- Believing the static wildcard also imports nested types
- Saying the wildcard is always fine / recommended by default