Java Import: The Importance of Imports in Java
A tweet from Kevlin Henney in August 2018 reopened an old can of worms:
The “issue” has never seemed a Big Deal® to me. Even so, a couple of things came to mind when I first read Kevlin’s tweet:
- Java is designed to work both ways: With wildcard imports or with specific ones. So, programmers who prefer one way or the other are using the language “as designed.”
- IDEs don’t necessarily default to specific imports. For example, the leading Java IDE on the market today, JetBrains IntelliJ IDEA, defaults to wildcard imports (well, it makes reasonable choices based on what imports are needed). And I’m pretty sure you can configure IDEs to your liking, too.
I didn’t really expect anything to come of the tweet, and I was a little surprised at the responses. For instance:
This surprised me in a couple of different ways.
- I didn’t realize James Bond was into software development.
- Why would anyone think import statements had any effect on class loading?
In case you were thinking that first point suggests I’m not treating the topic as seriously as a lot of other people, let me clarify: You’re right.
What is a little bit interesting is the fact many programmers regard this as an important point, and will defend their preference with great emotion.
In the first response to Kevlin’s original tweet, wildcard imports were labeled “bad practice” flatly, as if it were an established fact requiring no further explanation. And 007 isn’t the only one who thinks so. In a StackOverflow question from October, 2013, user2810581 (I can’t imagine naming my child user2810581; THX-1138, maybe, but not user2810581) reports getting conflicting advice from books and from her instructor: “I am a student, and a couple of the books I have been reading (Java for Dummies, for one) has said using the wildcard import statement is bad programming practice and encourage the reader to avoid using it. Whereas, in class, we are encouraged to use it. Can somebody please explain why it is poor programming practice?” So, the assumption is written into books as well as expressed on social media, also (apparently) without explanation.
In answer to a different StackOverflow question, from October 2008, Benjamin Pollack explains, “The only problem with it is that it clutters your local namespace. For example, let’s say that you’re writing a Swing app, and so need java.awt.Event, and are also interfacing with the company’s calendaring system, which has com.mycompany.calendar.Event”. That’s true, but it seems easy enough to specify individual classes when there is ambiguity, and otherwise use wildcard imports, if “clutter” is a concern for you. Oh, and, please accept my condolences if you’re writing a Swing app.
So, it looks like a matter of personal preference. Yet, it seems people are willing to spend substantial time and effort to force their tools to avoid generating wildcard import statements. The reasoning given in that StackOverflow answer: “It’s obvious why you’d want to disable this: To force IntelliJ to include each and every import individually. It makes it easier for people to figure out exactly where classes you’re using come from.”
Figuring out exactly where included code comes from is a Good Thing®. But if you’re using a sophisticated IDE such as IntelliJ IDEA (not to mention less-sophisticated ones, or any reasonably good text editor) you don’t have to figure that out manually. Most tools offer a way to search the project for references and declarations, and to help us identify the jars containing class files for which we don’t have the source.
You needn’t spell out every imported class in its own import statement, unless you happen to like that sort of thing. And if you don’t like it, you needn’t change existing code to use wildcard imports just to get the visual clutter out of your way; you can use the collapse feature of most editors to reduce all the import statements to a single line.
Because nearly all tools have these features, variations in personal preference don’t have to result in lengthy debates or convoluted work-arounds. Everyone can have code that looks the way they like it to look.
On a related note, in Java we expect to find packages that support related functionality. Our intent is typically to import a package rather than single classes on a one-off basis.
A practical rule of thumb could be to specify the package name down to the last node, but not necessarily write a separate import statement for each class. Seems to me that is intention-revealing without inviting visual clutter, as in Dan North’s example from the thread Kevlin started:
There are similar circular debates around import statements in other languages that have a concept similar to Java “packages,” too.
At my age, you’d expect me to have an opinion about everything. Maybe more than one. But in this case, I don’t. To me, the question of whether to use wildcard imports with Java is on par with burning questions such as:
- how far to indent
- tabs vs. spaces
- opening curly brace on same line or next line
- avoid static imports so you can see that assertEquals() is really Assert.assertEquals()
- others in a similar vein
Well, I might have just one opinion. It’s a small one.
I think we can save ourselves some grief if we strive for consistency within the community that maintains our code base. If that’s a single team, a group of teams within a larger organization, an Open Source project with multiple maintainers, or a worldwide community of developers using a given programming language, then that’s the “community.” If your community calls for wildcard imports or four space indentation or tabs or curly braces on the next line or whatever else, it’s generally best to go along with it; not because one way is technically or objectively better, but because of the usefulness of the principle of least astonishment.
We have more significant matters to invest our neurons in.