Concepts / Declaring Variables with Class Types

Declaring Variables with Class Types

An import directive lets you write a simple class name in the rest of a Java file instead of the full name, but it does not change the class or its type.

  • Programming

Why Full Class Names Get Long

Suppose you want to use the Color class from the java.awt package in a program. Its full name is java.awt.Color, and that full name is what Java needs in order to identify the class exactly. Writing the full name everywhere is precise but heavy. A program that uses several classes from several packages quickly becomes hard to read. Java offers a way to keep the precision while writing shorter names in the body of your code.

Before reading on, try this. A declaration such as a variable of type Color is written in a file. Predict whether the simple name Color alone is enough for the compiler to find the class, or whether something else must be written first. Hold your answer in mind while you trace the rest of this article, because the answer depends on a single directive that sits at the top of the file.

What an Import Directive Changes

Definition

An import directive lets you write a simple class name in the rest of a Java file instead of the full name, but it does not change the class or its type.

Although people often call an import line a statement, the source says it is more properly called an import directive, because it is not a statement in the ordinary sense. Its scope is the whole file. Once you place it, every later use of the simple name in that file is covered. The directive does not create a new class, and it does not give the class a different identity. It only allows the shorter spelling in the file where the directive appears.

The mapping is a connection, not a copy. The class referred to by the simple name and the class referred to by the full name are the same class. Keeping this distinction clear will help you read errors later, because a name that is spelled correctly can still fail if the directive it depends on is missing or misplaced.

Where the Import Directive Goes

The directive fills a fixed place in the file. It appears at the start of the file, after the package statement if the file has one, and it sits outside any class. A directive written inside a class body is not in the position the source describes, so it does not serve as the import for the rest of the file.

java
Notes on the code
  • The package statement comes first, if the file has one.
  • The import directive follows the package statement and sits outside the class.
  • The simple name Color is used in the class body, and the full name java.awt.Color is not written there.

Tracing the Color Declaration

The source uses a variable named rectColor of type Color as its illustration. The declaration takes the form of a type name, a variable name, and a semicolon. The clearest way to see the effect is to compare two versions of the same declaration.

Worked example

Declaring rectColor with and without the import

A file declares a variable rectColor whose type is the Color class from java.awt. Trace what the simple name Color needs in order to resolve.

  1. 1
    Version one: full name

    Without an import, the type is written as the full name, java.awt.Color rectColor = new java.awt.Color(255, 0, 0); Every reference to the class uses the full name, so nothing needs to be connected to the simple name.

  2. 2
    Version two: add the import

    Add import java.awt.Color; after the package statement and outside the class. The declaration can now read Color rectColor = new Color(255, 0, 0);

  3. 3
    Check what changed

    Only the spelling in the body changed. The class being declared is still java.awt.Color, and the type of rectColor is unchanged.

Result

The import shortens the name used in the file. It does not alter the class or the type of rectColor.

What do you think happens?

In the file shown above, if the import java.awt.Color line is removed but the body still says Color rectColor, does the compiler accept the name Color?

Reveal answer
Answer:

No. Without the import directive, the simple name Color is not connected to java.awt.Color, so the compiler cannot find the symbol.

The name is spelled correctly, but the directive it depends on is missing. The source notes that a correctly spelled name can still fail when its directive is absent. The fix is to restore the directive or to write the full name in that place.

Wildcard Imports and Their Reach

An import directive does not have to name one class. The source also shows a wildcard form, in which an asterisk stands in for the class name. The asterisk matches every class in the named package. This lets you abbreviate many class names at once, without writing one import line per class. Its reach is precise and easy to misjudge, so the two subsections below separate what it matches from what it does not.

Mistakes That Break Simple Names

When a program breaks after you switch to a simple class name, the cause is usually one of a few specific things. Use the list below as a checklist when you read the output of a failed build.

  • Common mistake

    Placing the import inside the class body

    What it looks like
    public class Shapes { import java.awt.Color; ... }
    Why it fails

    The directive has a fixed place. It sits at the start of the file, outside any class.

    Do this instead

    Move the import line above the class declaration and below the package statement, if one exists.

  • Common mistake

    Expecting a wildcard to reach subpackages

    What it looks like
    import java.*; then using a class from java.util.concurrent by its simple name
    Why it fails

    The wildcard matches the classes in the named package, not the contents of all its subpackages.

    Do this instead

    Import the subpackage explicitly, for example import java.util.concurrent.*; or the single class.

  • Common mistake

    Assuming the import changes the class

    What it looks like

    Believing that Color and java.awt.Color are two different classes after an import

    Why it fails

    The import does not change the class or its type. It only allows the shorter spelling.

    Do this instead

    Treat the simple name and the full name as two spellings of the same class.

  • Common mistake

    Misreading the cause of an error

    What it looks like

    Rewriting the declaration of rectColor when the actual problem is a missing import

    Why it fails

    The source notes that the cause is often the directive, not the declaration itself.

    Do this instead

    Check where the import sits and which package it names before changing the declaration.

Finding Where a Name Stops Resolving

The execution trace follows a short program through the stages described above. As you trace it, hold in mind where the result first diverges from what you expected. Often the divergence is not in the declaration itself but in whether the simple name has been connected to a full name at that point in the file.

Code walkthrough
import java.util.List;

public class Roster {
    public static void main(String[] args) {
        List<String> names = null;
        ArrayList<String> copy = null;
    }
}
  1. 1
    Line 1 the import directive connects the simple name List to java.util.List for the whole file.
  2. 2
    Line 5 List resolves, because the import covers it.
  3. 3
    Line 6 ArrayList has no import in this file, so its simple name is not connected to any full name here. This is the point where the simple name stops resolving.
  4. 4
    Fix: add import java.util.ArrayList; above the class, or write java.util.ArrayList in full at line 6.

Practice Tracing a Short Program

MEDIUM

A file begins with package demo; then import java.awt.Color; and then declares a class Painter whose main method contains Color rectColor = null; and later Point p = null;. Find the first line where a simple name stops resolving, and explain what import would fix it. Hint: check each simple name against the directives written above it, and remember that the directive must sit outside the class.

Hints
  • Check each simple name against the import directives that appear above it in the file.
  • Point is not connected by the import of Color. Consider which import line would connect it.
  • The import of Color does not affect any name other than Color.

Key Takeaways

  • An import directive lets you write a simple class name in the rest of a Java file instead of the full name, but it does not change the class or its type.
  • The directive belongs at the start of the file, after the package statement if present, and outside any class; its scope is the whole file.
  • A wildcard import with an asterisk matches every class in the named package, but it does not match subpackages, so java.* does not import the contents of all subpackages.
  • When a simple name fails, check where the import directive sits and which package it names before suspecting the declaration itself.