Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

importing classes using wildcards

Tags:

java

import

class

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.

like image 955
sherrellbc Avatar asked Jun 03 '13 23:06

sherrellbc


4 Answers

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.

like image 105
fge Avatar answered Oct 01 '22 03:10

fge


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.

like image 28
A-SM Avatar answered Oct 01 '22 01:10

A-SM


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.*;

like image 33
Craig Avatar answered Oct 01 '22 03:10

Craig


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.

like image 32
Vincent Ramdhanie Avatar answered Oct 01 '22 03:10

Vincent Ramdhanie