Static Import in Java: import static Explained - Quiz

Total: 5 questions

1. 

What is static import (import static) in Java, and what can you import with it?

Static import is an import static declaration that lets you use static fields, static methods, and static member types of another class by their simple name, without the class prefix. For example, after import static java.lang.Math.PI; you write PI instead of Math.PI.

It was introduced in Java 5. Only static members can be imported: instance fields and methods (such as String.length()) are out of reach. You also cannot import inaccessible members (for example, private ones) or members of classes in the default (unnamed) package.

2. 

What is the difference between a regular import and import static?

A regular import brings in types (classes and interfaces): after import java.util.List; you write List.of(1, 2). import static brings in static members of a class: after import static java.lang.Math.PI; you write PI instead of Math.PI.

The wildcard forms differ too: import java.util.*; means every type in the package, while import static java.lang.Math.*; means every static member of the class. The java.lang package is imported automatically only at the type level, so writing cos(PI) without a prefix still needs a static import.

Both kinds are compile-time only: the bytecode is the same as with fully qualified names, so there is no performance impact. Both go after the package statement and before the class declaration.

3. 

How does a single-static-import differ from a static-import-on-demand (*), and what happens when two wildcard imports bring in the same name?

A single-static-import (import static java.lang.Math.max;) brings in every static member with that name, including all overloads of max; you never list method parameters in an import. An on-demand import (import static java.lang.Math.*;) brings in every accessible static member of the class.

If import static java.lang.Integer.*; and import static java.lang.Long.*; both supply MAX_VALUE, nothing breaks until you use the name. Once you do, the compiler reports reference to MAX_VALUE is ambiguous.

The fix is to add a single-static-import for the member you want (it takes priority over wildcard imports) or to write the qualified name Integer.MAX_VALUE. In production code, explicit single imports are usually preferred because they show where each name comes from.

4. 

Why does toString(numbers) fail to compile inside a class even after import static java.util.Arrays.toString;?

Names declared in the class itself or inherited by it shadow statically imported names. Every class inherits toString() from Object, so the compiler looks up toString(numbers) among the class's own methods, finds the no-argument Object.toString(), and reports method toString in class Object cannot be applied to given types.

The fix is to qualify the call: Arrays.toString(numbers). The same applies to equals and hashCode: statically importing something like Objects.equals is useless because Object.equals always shadows it.

5. 

When should you use static import in Java, and when is it better to avoid it?

Static import pays off when a member name is self-explanatory and repeated often: math-heavy code with Math (sqrt, pow, PI), JUnit assertions (assertEquals, assertTrue), Stream API collectors (groupingBy, counting), and frequently used constants or enum values (MONDAY).

Avoid it when the class name carries meaning: of(1, 2) tells the reader nothing, while List.of(1, 2) does. Wildcard static imports from several classes also hurt readability and invite ambiguity. Oracle recommends using static import sparingly - only when you would otherwise repeat the class name many times - and importing constants instead of implementing a "constant interface" just to get them.

Page 1 of 1