Any reason to clean up unused imports in Java, other than reducing clutter?
Asked Answered
W

12

107

Is there any good reason to avoid unused import statements in Java? As I understand it, they are there for the compiler, so lots of unused imports won't have any impacts on the compiled code. Is it just to reduce clutter and to avoid naming conflicts down the line?

(I ask because Eclipse gives a warning about unused imports, which is kind of annoying when I'm developing code because I don't want to remove the imports until I'm pretty sure I'm done designing the class.)

Wholism answered 11/6, 2009 at 2:40 Comment(1)
You can also modify the "Save Action" settings by letting Eclipse perform some clean-ups, like organizing imports, removing unnecessary ones and adding tags like "Override". (It also formats your code, in particular)Hax
T
92

I don't think that performance problems or something like that are likely if you are not removing the imports.

But there could be naming conflicts, in rare cases like importing the list interface.

In Eclipse you can always use a shortcut (depends on OS - Win: Ctrl + SHIFT + O and Mac: COMMAND + SHIFT + O) to organize the imports. Eclipse then cleans up the import section removes all the stale imports etc. If you are needing a imported thing again eclipse will add them automatically while you are completing the statement with Ctrl + SPACE. So there is no need in keeping unused code in you class.

As always unused code will distract you and other people while reading the code and leaving something in your active code because of maybe I need it later is mostly seen as bad practice.

Talbert answered 11/6, 2009 at 2:48 Comment(3)
It's actually Ctrl+Shift+O on windows.Rabbinate
Ctrl+Shift+O on linux well. Probably the same on BSD.Lasonyalasorella
Another way to get to it the organize imports action is by clicking ctrl+3 (at least on windwos) and then typing imports. It is obviously slower then ctrl+shift+O but its a way to quickly find it (and many other actions that you either remeber or are just trying to find) even if you don't remember the specific shortcut for this.Lupita
E
61

One would be that if you remove the class referenced by the import from the classpath, you won't get a silly compiler error that served no purpose. And you won't get false positives when you perform a "where used" search.

Another (but this would be very specific in nature) would be if the unused import had naming conflicts with another import, causing you to use fully qualified names needlessly.

Addendum: Today the build server started failing compilation (not even test running) with an out of memory error. It ran fine forever and the check-ins didn't have any changes to the build process or significant additions that could explain this. After attempting to increase memory settings (this is running a 64 bit JVM on a 64 bit CentOS!) to something well beyond where the clients could compile, I examined the checkins one by one.

There was an improper import that a developer had used and abandoned (they used the class, auto-imported it, and then realized it was a mistake). That unused import pulled in a whole separate tier of the application which, while the IDE isn't configured to separate them, the build process is. That single import dragged in so many classes that the compiler attempted to compile without having the relevant dependent libraries in the classpath, that this caused so many issues that it caused the out of memory error. It took an hour to solve this problem caused by an unused import.

Emmeram answered 11/6, 2009 at 2:46 Comment(14)
@Yishai, if you use Eclipse look into Save Actions, which can normalize source code everytime you save.Handknit
@Thorbjørn, you can do the same thing in IDEA (basically - it doesn't really have a save event, it saves all the time) as well as optimize imports at checkin, but it is not enabled by default and this developer did not have it enabled.Emmeram
There's something wrong here. Unused imports don't affect the byte code in the slightest.Cobra
@EJP, although they don't affect the resulting bytecode, the compiler needs to resolve them to understand the bytecode it needs to create.Emmeram
I'm well aware of that but it doesn't explain the problem the poster described, unless it occurred at compile time, which wasn't stated.Cobra
@EJP, the whole addendum is talking about compile time ("build server started failing compilation").Emmeram
@Emmeram could you elaborate on exactly what happened and with what tool, because it is a bit difficult to understand without knowing more detail?Handknit
@ThorbjørnRavnAndersen, I can't really explain it better without a long elaboration on the structure of the project itself. The tools aren't that important to why it happened (Teamcity for the build, Intellij IDEA for the IDE).Emmeram
I still do not understand how the import alone could cause all this?Handknit
@ThorbjørnRavnAndersen, basically that import caused the compiler to attempt to compile a bunch of classes for which there was insufficient classpath support. The sheer volume of errors that created overran memory. We then restructured the project to prevent that from even being possible again.Emmeram
@Emmeram Sorry but I don't believe it. You've misdiagnosed this. The import should have no such effect, unless the class was actually used. All the import statement does is tell the compiler which package that class is in. The compiler only tries to compile implicitly when it needs type information about that class.Cobra
@EJP, you are assuming that the compiler parses the class lazily (note this was not a .* import), but I don't know why. Either way, the compiler output showed all the class errors, and removing the import stopped the problem. Make of that what you will.Emmeram
@Emmeram You are assuming that the compiler compiles every class mentioned in an import statement. I am a compiler writer and I can assure you it doesn't. I don't find this even remotely credible. I suggest that the real situation is more complex: for example a wrong import of a class with a certain name when the class intended had the same name but in a different package: possibly the same package as the class being compiled.Cobra
@EJP, there are no other classes in the project with the same name. I didn't assume that the compiler compiles every class, I observed the behavior of including an unused import. I don't know why the compiler tried to work out the dependencies of that class (which isn't the same thing as compiling it, I assume).Emmeram
P
11

From a purist point of view, any dependency is a "constraint" on the product and can thus cause maintenance problems later.

For example, let's assume that your program uses the class com.X.Y.Z.ObjectPool, and that later on you decide not to use it but never remove the import. If somebody else now wants to instantiate org.W.V.Y.ObjectPool and just refer to ObjectPool, they don't get any warning about it until somewhere down the line there's a casting problem or invocation problem.

This is, by the way, not an unrealistic scenario. Every time you had Eclipse ask you which specific version of X you wanted to import, and you picked one from among many packages, is a scenario where if you have had the import there you might have gotten the wrong choice without knowing about it.

Either way, you can ask Eclipse to clean these up for you

Pincushion answered 11/6, 2009 at 3:0 Comment(0)
A
3

Warning? Ask Eclipse to automagically clean them up for you. That's what IntelliJ does. If it's smart enough to warn you, it should be smart enough to clean them up. I'd recommend looking for an Eclipse setting to tell it to stop being such a nag and do something.

Apoloniaapolune answered 11/6, 2009 at 2:52 Comment(3)
Thats Save Actions. Personally I like that Eclipse only changes your code when you explicitly have asked for it.Handknit
@Thorbjørn: Agreed, especially if it is a class I've stopped using for a little bit but which I expect to be adding back in again shortly.Unfruitful
@Donal, well, that is what Ctrl-Space is for.Handknit
L
3

This has to do with clarity of the program useful for maintenance.

If you had to maintain a program you'll find how useful is to have a single class import per line.

Think about the following scenario:

import company.billing.*;
import company.humanrerources.*;

// other imports 


class SomeClass {
      // hundreds or thousands of lines here... 
    public void veryImportantMethod() {
      Customer customer;
      Employee comployee;
      Department dept. 
      // do something with them
     }
 }

When you're bugfixing or maintaining piece of code ( or only reading it ) it is very helpful for the reader to know to which package do the classes used belong to. Using the wildcard import as shown above doesn't help for that purpose.

Even with an IDE, you don't want to hover or jump to declaration and return, it is easier if you understand in terms of functionality what other packages and classes the current code depends on.

If this is for a personal project or something small, it really doesn't matter, but for something larger that have to be used by other developers ( and maintained through the years ) this is a MUST HAVE.

There is absolutely no performance difference with any.

Lecialecithin answered 10/12, 2009 at 12:9 Comment(0)
R
3

FYI, This caught me out, as I didn't think organize imports actually removed unused imports, I thought it just sorted them.

Automatically removing imports during a save operation caused me some grief when for example, during development or testing you have a problem and comment out some code, when you save it, the imports used by the commented out section of code are removed. Sometimes this is not a problem as you can undo (Ctrl+Z) the changes, but other times it is not so simple as you may have made other changes. I also had a problem where when I uncommented the code (I have previously commented out then saved, thus removing the imports for that code), it automatically tried to guess the imports that were needed and picked up the wrong ones (e.g I think I had a StringUtils class being used and it picked another one with the same name from the wrong library).

I prefer to manually organize imports rather than have it as a save action.

Rennarennane answered 1/2, 2011 at 1:19 Comment(0)
P
2

For eclipse i use this: window -> preferences -> java -> editor -> save action -> check the checkbox for organize imports (there are a lot of other useful stuff there too, like formatting, making fields final and so on..). So when i save my file eclipse removes the unessacry imports for me. In my opinion, if you don't need something then remove it (or let it be removed by eclipse).

Preference answered 19/1, 2010 at 15:56 Comment(0)
M
2

You could comment the unused import statements out and the warnings wont bother you but you can see what you had.

Montiel answered 6/12, 2016 at 13:4 Comment(1)
@DimaSan Actually it does: the question says I don't want to remove the imports until I'm pretty sure I'm done designing the class.Cadmann
D
2

An unused import still creates a dependency. If you don't realize that a dependency is only because of unused imports, you can waste time updating the module version, investigating vulnerability reports related to that module, etc.

In extreme cases, simply having the module available on the application's classpath—even if your code doesn't use it—can create exploitable vulnerabilities. For example, a deserialization gadget in the otherwise unused library could have a remote code execution vulnerability.

Making your code more readable should be reason enough to clean these up, but there are also real functional drawbacks in having unnecessary dependencies.

Dinkins answered 24/5, 2021 at 18:47 Comment(0)
G
1

There is no any performance impact, though for readability you can make it clean. Removing unused imports is quite simple in both Eclipse and IntelliJ IDEA.

Eclipse

Windows / Linux -   Ctrl+Shift+O

Mac -                       Cmd+Shift+O

IntelliJ IDEA or Android Studio

Windows / Linux -   Ctrl+Alt+O

Mac -                       Cmd+Alt+O

Grievous answered 4/6, 2015 at 4:20 Comment(0)
R
0

For me, one unused class import in a controller class created a compilation problem in Jenkins build after i deleted the imported class during code cleanup and committed the deletion in git without testing a build in local.

Rijeka answered 31/5, 2017 at 23:15 Comment(0)
S
-1

I read somewhere, some years ago, that every imported class would be loaded at runtime with the importing class. So removing unused, especially whole packages, would reduce memory overhead. Although I suppose that modern versions of java deal with that, so probably it is not a reason anymore.

And by the way, with eclipse you can use Ctrl+Shift+O to organize imports, but you can also configure a "cleaner" that deal with such things (and many others) each time you save a java file.

Sabu answered 12/6, 2009 at 19:37 Comment(3)
hmm.. i would be surprisedif that was the behavior.. i know classes aren't initialized (i.e. calling the static initializers) until first use, or until they are specifically requested by a custom loader. but if by "loaded" you just mean "read into memory but not processed" it is possible, though i doubt it.Wholism
actually, upon further thought, it should be fairly easy to test. compile code with unused imports, then use a "decompile" tool and see if the unused imports are still there or not. if not then either they are being removed by the compiler, or they are just there for convenience to the programmer.Wholism
Where on earth did you read that? It is completely and utterly incorrect, and always has been. Every class referenced by the code will be loaded, not including imports.Cobra

© 2022 - 2024 — McMap. All rights reserved.