★ wanayoo — archive 1999 http://developer.java.sun.com/developer/technicalArticles/Interviews/Packaging/index.htmlNouvelle recherche | Portail wanayoo
Java Technology Home Page
A-Z Index

Java Developer Connection(SM)
Technical Articles

Downloads, APIs, Documentation
Java Developer Connection
Tutorials, Tech Articles, Training
Online Support
Community Discussion
News & Events from Everywhere
Products from Everywhere
How Java Technology is Used Worldwide
 
Articles Index

It's All in the Packaging

Ian McFarland

Packages are Java's way of grouping classes together. This isn't much of an issue when you're first starting out. For beginners, it's quite adequate just to compile classes and leave them all in the same directory. Later on, though, when you start to feel like that one directory is getting a tad cluttered, it's a good time to invest a few brain cells in learning about packages.

Package statements look like this:

      package com.neo.ui;

This statement means that the class defined in this file belongs to the com.neo.ui package. So, for example, suppose you defined a class as follows:

      public class Widget extends Component

This means that your Widget class is part of the com.neo.ui package. When the Java1 virtual machine (JVM) looks for your Widget class, it will be looking for com.neo.ui.Widget. But what does that mean?

It means that Java will look in the com/neo/ui directory for a file named Widget.class when it tries to load this class. If your CLASSPATH is ~/java, it will look for ~/java/com/neo/ui/Widget.class. If your CLASSPATH is C:\Java it will look for C:\Java\com\neo\ui\Widget.class. Of course, your CLASSPATH will usually include your current working directory, so in addition to the above places, it would also look in the com/neo/ui directory relative to your current directory to find Widget.class.

If, for example, you wish to use this class from an applet on the server www.neo.com, and the applet is called MyApplet, your HTML might look like this:

      <APPLET CODE="MyApplet" 
CODEBASE="http://www.neo.com/Java/Classes" WIDTH="40" HEIGHT="30"> </applet>

In this case, the file MyApplet.class should be in the Java/Classes directory relative to the document root on your server, and Widget.class must be in Java/Classes/com/neo/ui.

And if you wish to refer to this class, you will need to let the compiler know which package it's in. You can do this one of two ways. The first, seldom used, but more explicit way is to declare a variable using the fully qualified name of the class:

  com.neo.ui.Widget myWidget = 
    new com.neo.ui.Widget("A Widget!");

The second and much more common way (in fact you've probably used it youself many times) is to import the package containing the widget. Include the following statement at the beginning of your .java file:

     import com.neo.ui.Widget;

From then on, you can just refer to that widget as Widget, and the compiler will know what kind of widget you mean, as shown:

      Widget myWidget = new Widget("A Widget!");

You can likewise import all of the classes in a package with the following syntax:

      import com.neo.ui.*;

That way, if you had defined both Widget and another class Gadget as being part of package com.neo.ui, you could refer to either by just their class name:

  import com.neo.ui.*;
      Widget myWidget = new Widget("A Widget!"); 
      Gadget myGadget = new Gadget();
So which is better?

Most of the time it really doesn't matter too much which of these approaches you take. The class files they produce will be identical. The only places where it makes any difference are in compile time, and in cases where you wish to use two different classes that have the same name.

The difference in compile time has to do with the fact that it takes the compiler a little longer to search through a longer list of possible class names to find a match. The more explicitly you tell it the class to which you're referring (through the import statement, or through the explicit use of fully qualified classnames), the less time it has to spend trying to match up the class to the package that contains it.

The other rare case, and the only one where it's actually necessary to use fully qualified class names, occurs when you intend to use two classes with exactly the same name:

 com.neo.ui.Button myFirstButton = 
   new com.neo.ui.Button("One kind of button");
 java.awt.Button mySecondButton = 
   new java.awt.Button("Another kind of button");

Reuse of names should be avoided where possible, as it makes code much harder to read and interpret (for the human programmer, though not for the Java Virtual Machine). Ten pages into the code, you might find it hard to remember whether myFirstButton referred to a regular java.awt.Button or to a custom com.neo.ui.Button. It also means that you'll have to type out the fully qualified class name every time you use it, since there will be no way for the compiler to know that you meant java.awt.Button when you simply typed Button. (Or was that com.neo.ui.Button?)

You may run into a situation where you have no choice about this, for example when using a third-party library with another third-party library, where both define an ImageButton. Other than that, though, it should be easy to avoid.

So what should I name my package?

There is a convention to name your packages based on the domain name of your company or of your web site. This helps to prevent name conflicts of the type mentioned above, but of a more intractable type. (Suppose you had two classes, from different providers, both named interface.Widget.) The domain name is reversed, so that the least specific part is at the left, and the more specific parts to the right. Therefore, neo.com becomes com.neo.

Within a domain, a lot depends on the organization of the entity the domain name represents. At a small company like Neo Communication, we break this down into client names next, so we use either com.neo.msp or com.neo.gcpw.

For individuals, breaking this down by email address is attractive, so you could have a name such as com.netcom.ix.netranger or com.aol.surfdog977653. The main thing is to assure that the name will be unique. For this reason, just using com.netcom or com.compuserve is really not enough.

Having decided on a unique identifier for all of your classes, package names are broken down further still based on the particular application or project the files belong to, or if they are general resources, according to category. com.neo.ui is the package where we keep all of our generic user interface classes. com.neo.imf.mcnotes is where I keep my McNotes project files. The main thing is that the structure make sense to you.

So what about protected data?

In addition to keeping files organized, packages help with encapsulation and data hiding. By using the protected keyword, variables can be made visible only to classes within the same package as the class to which the variables belong. It makes sense to group related classes into packages, so that they can share access to methods and variables, while hiding the complexity of their interaction from other objects that don't use that information. For example, a chat program might be defined within package com.neo.chat, but all the networking code might reside within com.neo.chat.network, and all the user interface code might reside within com.neo.chat.ui. This way, the size of the interface between the different sections can be kept small, so it's easier for teams to work on the same project, and for portions of a project to be revised without impacting other portions of a project.

Lessons most people learn the hard way

These are the hidden assumptions of Java that often bite beginners:

Bullet The package statement must be the first line of code in any file where it is used. (Comments excluded.)

Bullet The package to which an object belongs is implicitly imported and available within any file where such a declaration appears. Therefore, the following is legal:

      package com.neo.ui;
      import java.awt.Panel;
      public class WidgetPanel extends Panel { Widget[]
myWidgets;       .       .       .
}

Bullet The import statement only imports classes from the specified package, not from subpackages. This means that import com.neo.*; will import com.neo.FunApplet.class, but not com.neo.ui.Widget.class. This is to improve compiler performance and to mitigate namespace conflicts. You won't want to import all the image manipulation classes in java.awt.image every time you want to use something in java.awt, for instance.

Bullet You should also know that if you don't specify a package, your class becomes part of the "default package," which means that it has access to other classes not specifically belonging to other packages.

Where should you go from here?

Now you might want to take a look at all that code with the mysterious package statement at the beginning (remember that it must be the very first line of code), and see if the reasoning behind it is clearer. You might try using a package statement in some of your code, to group it all together. Don't forget that member classes of a given package must reside in a directory with the same name as the package, and that the directory itself (and not the class files) must be in the search path. And if you don't get it at first, reread the beginning of this article, and check to make sure you understand which directories are on the search path. It's a new way of thinking, but if you're persistent in trying to understand it, it sinks in eventually.

_______
1 As used on this web site, the terms "Java virtual machine" or "JVM" mean a virtual machine for the Java platform.


[ This page was updated: 12-Jan-2000 ]
Products & APIs | Developer Connection | Docs & Training | Online Support
Community Discussion | Industry News | Solutions Marketplace | Case Studies
Glossary - Applets - Tutorial - Employment - Business & Licensing - Java Store - Java in the Real World
FAQ | Feedback | Map | A-Z Index
For more information on Java technology
and other software from Sun Microsystems, call:
(800) 786-7638
Outside the U.S. and Canada, dial your country's AT&T Direct Access Number first.
Sun Microsystems, Inc.
Copyright © 1995-2000 Sun Microsystems, Inc.
All Rights Reserved. Terms of Use. Privacy Policy.