If I say:
import java.awt.event.ActionListener;
I get the ActionListener Class.
If I say:
import java.awt.event.*;
I get the event class including ActionListener?
Or better yet:
import java.awt.*;
I thought that if you included a class, like in the last two example, that you effectively imported that class and inherited all of its subclasses. But, when I use only the last line, for example, Eclipse often shows errors saying it cannot resolve certain items and suggests I include both the java.awt and java.awt.event.
The "wildcard" imports in Java only work to the immediate level at which classes are implemented.
That is, if you have classes A
, B
and C
, with fully qualified names:
com.foo.bar.A
;
com.foo.bar.B
;
com.foo.C
;
then importing com.foo.bar.*
will allow access to A
and B
without further ado; but C
will NOT be available.
In the same vein, importing com.foo.*
will readily have C
available, but not A
and B
.
Now:
I thought that if you included a class, like in the last two example, that you effectively imported that class and inherited all of its subclasses.
It does not. Even if B
"inherits" A
, if you choose to use the fully qualified import com.foo.bar.A
, it WILL NOT automatically import com.foo.bar.B
. You'll have to import B
separately. Which makes sense: nothing forces implementations of an interface or abstract class to be in the same package as their base interface/base class, for one; and in the same project, you may have two classes named B
, in different packages: what should the compiler do?
Now, according to coding style conventions, which you either make up for yourself or have to obey in your work environment, such wildcard imports may be purely and simply forbidden, and you'll have to import A
and B
separately. As to static imports, they have other problems...
Finally, note that by default, you can use all of java.lang.*
without having to declare an import.
java.awt.*
is different with java.awt.event.*
, the first one will import all the classes within java.awt
package, while the second one will import all the classes within java.awt.event
, the import function will only import classes, not packages.
From the Java Tutorials: Apparent Hierarchies of Packages
At first, packages appear to be hierarchical, but they are not. For example, the Java API includes a java.awt
package, a java.awt.color
package, a java.awt.font
package, and many others that begin with java.awt. However, the java.awt.color
package, the java.awt.font
package, and other java.awt.xxxx
packages are not included in the java.awt
package. The prefix java.awt
(the Java Abstract Window Toolkit) is used for a number of related packages to make the relationship evident, but not to show inclusion.
Importing java.awt.*
imports all of the types in the java.awt
package, but it does not import java.awt.color
, java.awt.font
, or any other java.awt.xxxx
packages. If you plan to use the classes and other types in java.awt.color
as well as those in java.awt, you must import both packages with all their files:
import java.awt.*;
import java.awt.color.*;
Remember that the import statement is just for convenience. It is there to make it possible for you to use the short name of a class rather than the fully qualified name.
The package name structure in Java corresponds to a directory structure. So you can think of it as a directory named java and in that directory there are several other directories such as awt and io etc.
When you say
import java.awt.*;
you are basically saying that you want to use the short name for all the classes in the directory named awt inside the directory named java. So if you use a class name in your code like this:
List mylist;
Then the compiler will attempt to find either a class named List in the current package or a class named java.awt.List.
So if you have a directory inside the awt directory called event and you have a class named ActionEvent in that directory, the fully qualified name is:
java.awt.event.ActionEvent
and the import statement above does not help. Hence the reason for needing another import statement
import java.awt.event.*;
Now, if you use the class ActionEvent the compiler looks for a class named ActionEvent in the current directory, or java.awt.ActionEvent or java.awt.event.ActionEvent until it finds one.
From Sun's documentation on Using Package Members:
At first, packages appear to be hierarchical, but they are not. For example, the Java
API includes a java.awt package, a java.awt.color package, a
java.awt.font package, and many others that begin with java.awt.
However, the java.awt.color package, the java.awt.font package, and
other java.awt.xxxx packages are not included in the java.awt package.
The prefix java.awt (the Java Abstract Window Toolkit) is used for a
number of related packages to make the relationship evident, but not
to show inclusion.
Importing java.awt.* imports all of the types in the java.awt package,
but it does not import java.awt.color, java.awt.font, or any other
java.awt.xxxx packages. If you plan to use the classes and other types
in java.awt.color as well as those in java.awt, you must import both
packages with all their files:
import java.awt.*;
import java.awt.color.*;
If you have time, you will probably do well to read through the entire Packages trail from sun which goes over the basics and more complicated concepts thoroughly. From the language in your question, where you refer to the second import statements as including particular classes, it sounds like you're not understanding that you're actually referring to packages.