Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures


Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips


Submit News
Search the site here...
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Learn Java: Programming Articles, Examples and Tips - Page 419

Previous 1060 Stories (530 Pages, 2 Per Page) Next

Java Import Statement Cleanup

Go to all tips in Story by Dr. Kabutz

The Java Specialists' Newsletter [Issue 051] - Java Import Statement Cleanup

Author: Dr. Cay S. Horstmann

JDK version:

Category: Software Engineering

You can subscribe from our home page: http://www.javaspecialists.co.za (which also hosts all previous issues, available free of charge Smile

Welcome to the 51st edition of The Java(tm) Specialists' Newsletter sent to over 3800 readers in 84 countries, with latest additions of Chile and Kenya. I always get excited when I see an African name on my new subscriber list, since at the moment I only have subscribers in Africa from: Egypt, Ghana, Kenya, Mauritius, Morocco, Namibia, Nigeria, South Africa and Zimbabwe. I say "umkelekile" (welcome in Xhosa) to my new subscriber from Kenya.

This newsletter attracts the elite of Java programmers, since we cover things that are not usually mentioned on Java newsletters. If you are a subscriber to this newsletter, it makes you part of the "elite" Smile A relatively new subscriber to my newsletter is Dr. Cay S. Horstmann, famous Java author in the "Core Java" series. Cay very kindly pointed me to an article that he wrote about a tool he created for cleaning up import statements. Seeing that I am an amateur writer, I did not dare "edit" the article in case I completely messed it up, so I am sending it to you as is, with just the syntax highlighting added and font changed (almost like some students [and lecturers] do at universities). You can have a look at the original article on http://horstmann.com/articles/ImportCleaner.html.

Before we listen to what Dr. Horstmann has to say about the topic, I would like to make a few of my own comments about the subject. Having code with unnecessary import statements looks unprofessional, but how do you keep them up-to-date? An IDE which does this very nicely is Eclipse. You click on the class and say "Organize Imports", and bang! it beautifies your import statements. I am sure there are other IDEs out there that can do the same. However, if you don't have such an IDE, the technique described in this newsletter is a great way of solving this problem.

After my last Design Patterns Course, one of my students sent me the following note: "I really enjoyed the course. I origionally thought it was going to be about learning to draw UML diagrams. I was pleasantly surprised to discover the course was actually about different programming strategies. I learnt some very cool tricks and new way of aproaching the problems of designing a system. A must for those who wish to design maintainable systems." Please send me an email if your company would like to receive training in Design Patterns.

Java Import Statement Cleanup


In the Java programming language, the names of classes that are defined inside packages always start with the package name. For example, the class name


starts with the name of the package java.awt. As a convenience to programmers, the import mechanism can be used to reference classes without the package name. For example, it is tedious to write

java.awt.Rectangle box = new java.awt.Rectangle(5, 10, 20, 30);

You can use the more convenient form

Rectangle box = new Rectangle(5, 10, 20, 30);

provided you import the class.

Classes in the same package are automatically imported, as are the classes in the java.lang package. For all other classes, you must supply an import statement to either import a specific class

import java.awt.Rectangle;

or to import all classes in a package, using the wildcard notation

import java.awt.*;

Importing classes can lead to ambiguities. A class name is ambiguous if it occurs in two packages that are imported by wildcards. For example, suppose a program contains the imports

import java.awt.*;
import java.util.*;

The class name List is now ambiguous because there are two classes java.awt.List and java.util.List. You can resolve the ambiguity by adding a specific import of the class name:

import java.awt.*;
import java.util.*;
import java.util.List;

However, if you need to refer to both java.awt.List and java.util.List in the same source file, then you have crossed the limits of the import mechanism. You can use an import statement to shorten one of the names to List, but you need to reference the other by its full name whenever it occurs in the source text.

The Problem

Ambiguities are unpleasant because they can arise over time, as libraries expand. For example, in JDK 1.1, there was no java.util.List class. Consider a program that imports java.awt.* and java.util.* and uses the name List as a shortened form of java.awt.List. That program compiles without errors under JDK1.1 but fails to compile in Java 2.

Therefore, the use of wildcards for imports is somewhat dangerous. However, importing each class can lead to long import lists that are tedious to manage, especially as code is moved from one class to another during development.

To illustrate this, consider the import list in one of my recent files.

import java.awt.*;
import java.awt.geom.*;
import java.io.*;
import java.util.*;

It turned out that I really needed

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

(Apparently, the need for importing java.io.* had gone away at some point during the program's evolution)

Thus, a problem that Java programmers face is how to keep import lists up-to-date when programs change.

Potential Solutions

One time-honored solution of checking import lists is to comment out one line at a time until compiler errors go away. Naturally, that is tedious.

Another solution is to stop using import lists altogether and referencing the full class names at all times. Naturally, that too is tedious.

Several compilers emit lists of classes that they load as they compile a program. For example, if you run the compiler in the Sun J2SE SDK 1.4 with the -verbose option, you get a list such as

[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/Font.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/Graphics2D.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/Stroke.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/font/FontenderContext.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/geom/Line2D.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/geom/Point2D.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/geom/Rectangle2D.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/util/ArrayList.class)]
[loading ./AbstractEdge.class]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/lang/Object.class)]
[loading ./Edge.class]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/io/Serializable.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/lang/Cloneable.class)]
[loading ./LineStyle.class]
[loading ./ArrowHead.class]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/lang/String.class)]
[checking SegmentedLineEdge]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/Graphics.class)]
[loading ./SerializableEnumeration.class]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/util/AbstractList.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/util/AbstractCollection.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/geom/Line2D$Double.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/Shape.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/text/CharacterIterator.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/lang/Comparable.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/lang/CharSequence.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/geom/Point2D$Double.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/awt/geom/RectangularShape.class)]
[loading /usr/local/j2sdk1.4.0/jre/lib/rt.jar(java/text/AttributedCharacterIterator.class)]

It would be an easy matter to write a script that transforms this output into a set of import statements. However, the output contains classes that don't actually need to be imported (such as CharSequence and AttributedCharacterIterator). These classes are loaded because some of the loaded classes depend on them. It is not clear (at least to me) how one can weed out the unneeded classes.

I used a different approach. I wrote a utility that harvests the class file. Unlike source files, class files never contain shortened class files. Even standard classes such as java.lang.String are referenced by their full names.

Class files contain the names of classes as well as field and method descriptors that contain class names (in an odd format, such as Ljava/lang/String; ). To harvest the class names, one must know the layout of the constant pool and the field and method descriptors. The class file format is well-documented--see the references at the end of this document--and only moderately complex.

The ImportCleaner Program

The ImportCleaner program parses one or more class files, harvests the class names, removes the unnecessary ones, sorts the remaining ones, and prints out a list of import statements to System.out.

Since ImportCleaner parses class files, your source file must first be compiled (presumably with a less-than-optimal import statement set). Then run ImportCleaner on the class file, capture the output, and paste the import lines into your source file.

For example, to run ImportCleaner on its own class files, you use

java -jar importcleaner.jar ImportCleaner

(You can find the ImportCleaner class files by unzipping importcleaner.jar).

The result is this list of imports, printed to System.out:

import java.io.DataInput;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

Typically, your next step is to capture that list of imports and paste it into your source file.

If your source file contains multiple top-level classes, then you need to list all of them on the command line. For example,

java -jar importcleaner.jar MyClass MyHelperClassThatIsDefinedInTheSameFile

However, inner classes are located automatically.

You can supply the name of a class in any of the following forms:

  • without suffix: MyClass
  • with .class suffix: MyClass.class
  • with .java suffix: MyClass.java

    The ImportCleaner program strips off the suffixes and then looks for the file MyClass.class and all files of the form MyClass$*.class (for inner classes).

    If your class file is located in a package, you need to invoke ImportCleaner from the base directory. For example, if you use the package com.mycompany.myproject, invoke ImportCleaner from the directory that contains the com directory. You can supply the package name in either of the following forms:

  • using periods as separators: com.mycompany.myproject.MyClass
  • using the separator of your file system: com/mycompany/myproject/MyClass (or on Windows)

    Capturing the output is very easy if you use the shell mode in Emacs. Other good programming editors have similar features. Alternatively, you can redirect the output to a file:

    java -jar importcleaner.jar class(es) > outputfile

    The program takes the following options:

  • -wildcard: This option produces an import list with wildcards instead of individual class names.
  • -keepall: This option keeps all imports, including the ones from java.lang and the current package. The default is to suppress the java.lang package and the current package
  • -usecalls: This option harvests method calls, which is sometimes beneficial to guess local variable types (see the Limitations section below). On the other hand, method calls can lead to spurious imports. This happens when you supply a parameter of a subclass type or catch a return value in a variable of a superclass type. For example, your code may call the constructor java.io.DataInputStream(java.io.InputStream) and pass a parameter of type java.io.FileInputStream, like this:
    DataInputStream in = new DataInputStream(new FileInputStream(file));
    Harvesting the method call yields the spurious import java.io.InputStream. Such spurious imports are generally harmless but unsightly.

    Download and Installation

    The usual.

    1. Download the file importcleaner.jar . With some browsers, you may need to right-click on the link and select a menu option such as "Save Link As".
    2. Save it in your favorite location
    3. Open a command shell
    4. Run java -jar your/favorite/location/importcleaner.jar options class(es)


    The program is distributed under the GNU General Public License . Source code and a copy of the license are contained in the JAR file.


    Unfortunately, constants are not included in the class files, so this utility will miss them. Typical examples are:


    Also, the types of local variables are not included in the class file. This sounds like a big problem, but fortunately, the same class or interface name is often used in a method or field descriptor as well. To illustrate the issue, consider this code:

    public void draw(Graphics2D g2) {
      Stroke oldStroke = g2.getStroke();
      g2.setStroke(new BasicStroke());
      // . . .

    ImportCleaner includes java.awt.Graphics2D because it appears in the method signature of the processed class. It includes java.awt.BasicStroke because of the constructor call. But by default it won't include java.awt.Stroke since there is no guaranteed reference for it in the source file.

    A remedy is to recompile after pasting in the ImportCleaner output. Then look at the error messages and manually insert the missing imports. It sounds bad, but in actual practice it doesn't seem to be all that bothersome.

    Another remedy would be to use fully qualified class names in this situation.

    You may also wish to use the -usecalls option. That option harvests method calls. In our example, that option finds the java.awt.Stroke class from the ()Ljava/awt/Stroke; method descriptor of the Graphics2D.getStroke method. Harvesting method descriptors is not the default because it can lead to spurious imports. (See the description of the -usecalls option for more information.)


  • The class file format is documented as part of the Java Virtual Machine specification ( http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html ). I found the source code at http://www.mcmanis.com/~cmcmanis/java/dump/ helpful to gain a clearer understanding of the class file format.
  • ImportScrubber (http://importscrubber.sourceforge.net/ ) seems to follow a similar approach as my ImportCleaner, and it has a GUI. BCEL (http://jakarta.apache.org/bcel/ ) is a library for reading and modifying class files used by ImportScrubber.
  • Importifier (http://javadude.com/tools/importifier/ ) is yet another tool for the same purpose, but it can't handle default packages.
  • A tool available at http://www.componative.com/downloads/impcleandoc.phtml harvests the output of the Jikes compiler.
  • TIM (http://www.chive.com/tim.htm ) is a commercial program for import management.

    That's it for this week.

    Kind regards


    P.S. Even though my newsletter template says that Maximum Solutions, South Africa, has the copyright on this newsletter, the copyright of the content of the article belongs to Dr. Cay S. Horstmann. Please contact him if you would like to publish this article anywhere.

    Copyright 2000-2004 Maximum Solutions, South Africa

    Reprint Rights. Copyright subsists in all the material included in this email, but you may freely share the entire email with anyone you feel may be interested, and you may reprint excerpts both online and offline provided that you acknowledge the source as follows: This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information.

    Java and Sun are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Maximum Solutions is independent of Sun Microsystems, Inc.

  • 15828 bytes more | Printer Friendly Page  Send to a Friend | Score: 0
    Posted by jalex on Monday, November 28, 2005 (00:00:00) (4105 reads)

    Q: Can I write sin(x) instead of Math.sin(x)?

    Go to all tips in Java IAQ by Peter Norvig

    Q: Can I write sin(x) instead of Math.sin(x)?

    Answer: Short answer: no. Get used to writing the class name to access static methods from outside the class. However, if you insist on a longer answer ...

    If you only want a few methods, you can put in calls to them within your own class:
    public static double sin(double x) { return Math.sin(x); }
    public static double cos(double x) { return Math.cos(x); }
    Static methods take a target (thing to the left of the dot) that is either a class name, or is an object whose value is ignored, but must be declared to be of the right class. So you could save three characters per call by doing:
    // Can't instantiate Math, so it must be null.
    Math m = null; 
    java.lang.Math is a final class, so you can't inherit from it, but if you have your own set of static methods that you would like to share among many of your own classes, then you can package them up and inherit them:
    public abstract class MyStaticMethods { 
      public static double mysin(double x) { ... } 
    public class MyClass1 extends MyStaticMethods { 

    Peter van der Linden, author of Just Java, recommends against both of the last two practices in his FAQ. I agree with him that Math m = null is a bad idea in most cases, but I'm not convinced that the MyStaticMethods demonstrates "very poor OOP style to use inheritance to obtain a trivial name abbreviation (rather than to express a type hierarchy)." First of all, trivial is in the eye of the beholder; the abbreviation may be substantial. (See an example of how I used this approach to what I thought was good effect.) Second, it is rather presumptuous to say that this is very bad OOP style. You could make a case that it is bad Java style, but in languages with multiple inheritance, this idiom would be more acceptable.

    Another way of looking at it is that features of Java (and any language) necessarily involve trade-offs, and conflate many issues. I agree it is bad to use inheritance in such a way that you mislead the user into thinking that MyClass1 is inheriting behavior from MyStaticMethods, and it is bad to prohibit MyClass1 from extending whatever other class it really wants to extend. But in Java the class is also the unit of encapsulation, compilation (mostly), and name scope. The MyStaticMethod approach scores negative points on the type hierarchy front, but positive points on the name scope front. If you say that the type hierarchy view is more important, I won't argue with you. But I will argue if you think of a class as doing only one thing, rather than many things at once, and if you think of style guides as absolute rather than as trade-offs.

    This tip is reprinted on JavaFAQ.nu by by courtesy of Peter Norvig I am thankful for his important contributions to my site - 21 Infrequently Answered Java Questions. Alexandre Patchine

    2174 bytes more | Printer Friendly Page  Send to a Friend | Score: 0
    Posted by jalex on Wednesday, November 23, 2005 (00:00:00) (3036 reads)

    Previous 1060 Stories (530 Pages, 2 Per Page) Next

    530| 529| 528| 527| 526| 525| 524| 523| 522| 521| 520| 519| 518| 517| 516| 515| 514| 513| 512| 511| 510| 509| 508| 507| 506| 505| 504| 503| 502| 501| 500| 499| 498| 497| 496| 495| 494| 493| 492| 491| 490| 489| 488| 487| 486| 485| 484| 483| 482| 481| 480| 479| 478| 477| 476| 475| 474| 473| 472| 471| 470| 469| 468| 467| 466| 465| 464| 463| 462| 461| 460| 459| 458| 457| 456| 455| 454| 453| 452| 451| 450| 449| 448| 447| 446| 445| 444| 443| 442| 441| 440| 439| 438| 437| 436| 435| 434| 433| 432| 431| 430| 429| 428| 427| 426| 425| 424| 423| 422| 421| 420|
    | 418| 417| 416| 415| 414| 413| 412| 411| 410| 409| 408| 407| 406| 405| 404| 403| 402| 401| 400| 399| 398| 397| 396| 395| 394| 393| 392| 391| 390| 389| 388| 387| 386| 385| 384| 383| 382| 381| 380| 379| 378| 377| 376| 375| 374| 373| 372| 371| 370| 369| 368| 367| 366| 365| 364| 363| 362| 361| 360| 359| 358| 357| 356| 355| 354| 353| 352| 351| 350| 349| 348| 347| 346| 345| 344| 343| 342| 341| 340| 339| 338| 337| 336| 335| 334| 333| 332| 331| 330| 329| 328| 327| 326| 325| 324| 323| 322| 321| 320| 319| 318| 317| 316| 315| 314| 313| 312| 311| 310| 309| 308| 307| 306| 305| 304| 303| 302| 301| 300| 299| 298| 297| 296| 295| 294| 293| 292| 291| 290| 289| 288| 287| 286| 285| 284| 283| 282| 281| 280| 279| 278| 277| 276| 275| 274| 273| 272| 271| 270| 269| 268| 267| 266| 265| 264| 263| 262| 261| 260| 259| 258| 257| 256| 255| 254| 253| 252| 251| 250| 249| 248| 247| 246| 245| 244| 243| 242| 241| 240| 239| 238| 237| 236| 235| 234| 233| 232| 231| 230| 229| 228| 227| 226| 225| 224| 223| 222| 221| 220| 219| 218| 217| 216| 215| 214| 213| 212| 211| 210| 209| 208| 207| 206| 205| 204| 203| 202| 201| 200| 199| 198| 197| 196| 195| 194| 193| 192| 191| 190| 189| 188| 187| 186| 185| 184| 183| 182| 181| 180| 179| 178| 177| 176| 175| 174| 173| 172| 171| 170| 169| 168| 167| 166| 165| 164| 163| 162| 161| 160| 159| 158| 157| 156| 155| 154| 153| 152| 151| 150| 149| 148| 147| 146| 145| 144| 143| 142| 141| 140| 139| 138| 137| 136| 135| 134| 133| 132| 131| 130| 129| 128| 127| 126| 125| 124| 123| 122| 121| 120| 119| 118| 117| 116| 115| 114| 113| 112| 111| 110| 109| 108| 107| 106| 105| 104| 103| 102| 101| 100| 99| 98| 97| 96| 95| 94| 93| 92| 91| 90| 89| 88| 87| 86| 85| 84| 83| 82| 81| 80| 79| 78| 77| 76| 75| 74| 73| 72| 71| 70| 69| 68| 67| 66| 65| 64| 63| 62| 61| 60| 59| 58| 57| 56| 55| 54| 53| 52| 51| 50| 49| 48| 47| 46| 45| 44| 43| 42| 41| 40| 39| 38| 37| 36| 35| 34| 33| 32| 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1|

    Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

    RSS feed Java FAQ RSS feed Java FAQ News     

        RSS feed Java Forums RSS feed Java Forums

    All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

    Interactive software released under GNU GPL, Code Credits, Privacy Policy