Imports considered annoying and pointless

December 01, 2007

What is really the point of import statements in Java? Am I meant to believe that while perl, vim, find, eclipse, emacs, or any other tool written in the last decade can locate my class files that javac cannot? Couldn't javac, when faced with a usage of the class ArrayList, figure out that since the only fucking class named ArrayList available to it is in java.util that that might possibly be the class I mean? Other than resolving ambiguities, imports are a manual way to accomplish what the compiler could much more easily. Plus, removing them would reduce pointless coupling, improve maintenance and result in a class header that provided actual value, and not a shitload of lines to fold and skip over.
  • But imports help the compiler locate classes! - Why should I help the compiler locate classes? Why put a fully automatable task in the hands of a developer? Are you telling me the compiler can't index the classpath to more efficiently search at compile-time?
  • But imports let you know class dependencies - No, they don't. Only if you don't use star imports and only if you import only what you need would this be the case. However, not really, because your class could Class.forName. And, honestly, how much time do you spend looking at the import statements to perform this analysis? An automated tool could provide this information much more correctly and completely
  • But how would I know what classes are in a jar and what are in the codebase? - You'd know the same way the compiler knows. And, to be honest, the code should be written for the maintainers, not for the new kids. Anyone new to a codebase can, relatively quickly, figure out what is in the code base and what isn't. This, along with proper tools for locating classes integrated into your IDE would be much better than looking at import statements and grep'ing the output of jar tvf.
I think an approach the addresses the above concerns without adding a lot of cruft is to redefine what we mean by "package". In Java parlance, "package" is really just a directory used to organize classes and ensure unique naming. Conceptually, however, a "package" is a singular unit. For example, Apache's commons-lang contains nine Java packages, but it's really only, conceptually, one package. I think some changes to the language to help us all out would improve things. Wouldn't this be much more readable source code:
package myapp;
// no point in putting the dir-structure as dots, the compiler

// can figure it out.  Instead we indicate that this class, whever

// it is, is part of the conceptual package "myapp"

import commons-lang[2.1,];     // check for version 2.1 or greater

import commons-logging[1.0.*]; // check for version 1.0.* only

import j2ee[5.0,5.3];          // check for any version from 5.0 to 5.3

clarify java.util.Date;

public class Whatever
    public static void main(String args[]) 
        Date date = new Date();
        // whatever else

This syntax that I just made up is explicit and much more powerful than import statements. You declare your version requirements and dependencies in a different way than clearing up ambiguities. The compiler could even issue warnings when you import things you don't use. It would not be terribly difficult for the compiler to provide this service, and it would keep it in the language and not in the hands of some unwieldy external tool or IDE. I don't know, this just seems fairly obvious to me, and I'm surprised that Java continues the "not much better than #include" method of linking things together.