In my project I have a shapes package which has shapes I designed for my graphics program, e.g., Rectangle and Circle. I also have one or two more packages that have the same names as java.awt classes.
Now, since I do not want to rename every class in my codebase, to show my source files which class I mean when I, say, declare a new Rectangle, I need to either:
1- import the rectangle class explicitly, i.e., import shapes.Rectangle
or
2- import only the java.awt classes I need and not import java.awt.* which automatically includes the awt.Rectangle
Now the problem is that both ways result in a lot of importing. I currently have an average of 15-25 imports in each source file, which is seriously making my code mixed-up and confusing.
Is too many imports in your code a bad thing? Is there a way around this?
Yes, too many imports is a bad thing because it clutters your code and makes your imports less readable.
Avoid long import lists by using wildcards.
Kevlin Henney talks about this exact Stack Overflow question 27:54 into his presentation Clean Coders Hate What Happens to Your Code When You Use These Enterprise Programming Tricks from NDC London 16-20 Jan 2017
If you use glob imports, it's possible to break your code with a namespace clash just by updating a dependency that introduces new types (typically not expected to be a breaking change). It could be a pain to fix in a large codebase that was liberal with their use of glob imports. That is the strongest reason I can think of for why it's a good idea to specify dependencies explicitly.
It's easier to read code which has each of the imports specified,
because you can see where types are coming from without requiring IDE
specific features and mouse hovering, or going through large pages of library documentation. Many people read a lot of code outside the IDE in code review, diffs, git history, etc.
Another alternative is to type the fully qualified class name as you need it. In my example, there are two Element objects, one created by my org.opensearch.Element and the other org.w3c.dom.Element.
To resolve the name conflict, as well as to minimize import "clutters", I've done this (in my org.opensearch.Element class):
public org.w3c.dom.Element toElement(org.w3c.dom.Document doc) { /* .... */ }
As you can see, the return Element type is fully-typed (i.e., I've specified the fully-qualified class name of Element).
Problem solved! :-)
I use explicit imports, and have done so for many years. In all my projects in the last decade this has been agreed with team members, and all are happy to agree to to use explicit imports, and avoid wildcards. It has not been controversial.
In favour of explicit imports:
precise definition of what classes are used
less fragile as other parts of the codebase changes
easier to code review
no guessing about which class is in which package
In favour of wildcards:
less code
easier to add and maintain the imports when using a text editor
Early in my career, I did use wildcard imports, because back then IDEs were not so sophisticated, or some of us just used text editors. Managing explicit imports manually is quite a bit of effort, so wildcard imports really help.
However at least once I was bitten by the use of wildcard imports, and this lead be to my current policy of explicit only.
Imagine you have a class that has 10 wildcard imports, and it compiles successfully. Then you upgrade 5 jar files to newer versions (you have to upgrade them all, because they are related). Then the code no longer compiles, there is a class not found error. Now which package was that class in? What is the full name of the class? I don't know because I'm only using the short name, now I have to diff the old and new versions of the jars, to see what has changed.
If I had used explicit imports, it would be clear which class had been dropped, and what it's package was, and this which jar (by looking of other classed in that package) is responsible.
There are also problems reading code history, or looking at historic merges. When you have wildcard imports there is uncertainty for the reader about which class is which, and thus what the semantics of the code changes are. With explicit imports you have a precise description of the code, and it acts as a better historical record.
So overall the benefit of the small amount of extra effort to maintain the import, and extra lines of code are easily outweighed by extra precision and determinism given by explicit imports.
The only case when I still use wildcards, is when there are more that 50 imports from the same package. This is rare, and usually just for constants.
Update1: To address the comment of Peter Mortensen, below...
The only defence Kevlin Henney makes in his talk for using wildcards is that the name collision problem doesn't happen very often. But it's happened to me, and I've learnt from it. And I discuss that above.
He doesn't cover all the points I've made in my answer above. -- But most importanly, I think the choice you make, explicit or wildcard, doesn't matter that much, what matters is that everyone on the project/codebase agree and use a consistent style. Kevlin Henney goes on to talk about cargo-cult programming. My decisions as stated above are based on personal lessons over decades, not cargo cult reasoning.
If I was to join a project where the existing style was to use wildcards, I'd be fine with it. But if I was starting a new project I'd use precise imports.
Interestingly in nodejs there is no wildcard option. (Although you do have 'default' imports, but it's not quite the same).
It's subjective and depends greatly on the circumstances. I sometimes bounce between the two.
It is a general good practice to be specific by default but it can also be higher maintenance. It's not a perfect rule. However being more specific (higher initial cost) will tend to reveal itself earlier through measurable or perceptible drag where as being lazy by default tends to manifest as a problem more adversely.
Over including of entire namespaces can create bloat and clashes as well as hide changes in structure but in certain cases it may outweigh the benefit.
To give a simple case:
I use a package with a hundred classes.
What if I use one of its classes?
What if I use all but one of them?
It's similar to the whitelist versus blacklist problem.
In an ideal situation the package hierarchy will subdivide package types enough to establish a good balance.
In certain systems I've seen people do the equivalent of import *. Perhaps the most horrifying case is when I saw someone do something similar to apt install *. Though it seemed clever so as to never have to worry about missing dependencies it imposed enormous burdens that far outweighed any benefit.
All things can be taken to the extreme. For example I could argue for the utility of imports as close to as needed but if we're going to do that why not just always use the fully qualified names all the time?
Problems like this are annoying as the low cognitive load of consistency is always preferable but when it comes down to it in various given circumstances you may need to play it by ear.
It's important to be proportionate. Doing something a thousand times to avoid something that happens one time, self presents and takes about as much effort to fix tends to result in a waste.
Different objectives may make "too many" imports a good thing. I have a custom JavaScript framework which would likely horrify many at a glance for its stacks of imports.
What's not immediately obvious is that this is part of a deliberate strategy.
This allows it to be easy In being able to more cleanly package the code with all its specific dependencies and then transmit that over a network.
Imports have a plug nature at build time to alternate dependencies for each given platform target.
This tends not to be as much as a problem for languages that are less dynamic and that do not suffer greatly (or at all) from the overhead excessively importing namespaces. The moral of this story is that import strategies can vary enormously but be valid for their given circumstances. You can only go so far in taking general approaches.
In each situation you will need to have your bearings and a sense of the lay of the land. If the import conventions and structure is causing a nuisance then it's necessary to narrow down the how and why. Too many imports may not be the result of a specific strategy but things such as packing too much into a single file. At the same time some files are naturally large and naturally require many imports.
Badly applied separation of concerns or organisation in failing to keep related things together can create a graph with grossly excessive edges where that can be reduced with greater organisation. To some degree it's not abnormal for code to be clustered by specific dependencies more so specific dependencies than the more general ones.
If a code base is well organised into a graph that is fairly close to optimal with neither excessive splitting, merging and minimal distance between things you will tend to find that even if being specific with imports the majority of cases will tend to stay within a reasonable size.
I don't get all the non-answers posted here.
Yes, individual imports are a bad idea, and add little, if anything, of value.
Instead just explicitly import the conflicts with the class you want to use (the compiler will tell you about conflicts between the awt and shapes package) like this:
import java.awt.*;
import shapes.*;
import shapes.Rectangle; // New Rectangle, and Rectangle.xxx will use shapes.Rectangle.
This has been done for years, since Java 1.2, with awt and util List classes. If you occasionally want to use java.awt.Rectangle, well, use the full class name, e.g., new java.awt.Rectangle(...);.
It's normal in Java world to have a lot of imports - you really need to import everything. But if you use an IDE, such as Eclipse, it does the imports for you.
It's a good practice to import class by class instead of importing whole packages
Any good IDE, such as Eclipse, will collapse the imports in one line, and you can expand them when needed, so they won't clutter your view
In case of conflicts, you can always refer to fully qualified classes, but if one of the two classes is under your control, you can consider renaming it (with Eclipse, right click on the class, choose menu Refactor → Rename, it will take care to update all its references).
If your class is importing from AWT and from your package of shapes, is ok. It's ok to import from several classes; however, if you find yourself importing from really lots of disparate sources, it could be a sign that your class is doing too much, and need to be split up.
Related
I was working with Typescript and Javascript and I stopped for a bit thinking about namespaces and how we organize code in Java.
Now, pretty often I see multiple classes with the same purpose, just for use with different data, being placed in different packages with different names.
While placing those classes in different packages is a good practice to maintain the project/module in a good state, why would we have to give them different names? I mean, their purpose is the same.
I can answer this question myself: because often we use those classes inside the same unit and they would clash, thus requiring a long full package specification for one or the other.
But aren't we violating the DRY principle? We should use our directory (package) structure to understand in which domain space those classes works.
As I wrote above, I suppose many developers aren't respecting this DRY principle just to avoid long package names. Then, why are we creating those monstruos package hierarchies?
Googling "Java packages best practices" results in suggestions such as:
com.mycompany.myproduct.[...]
Where do those suggestions come from? Aren't we just wasting space?
We obviously do not want to write that every time.
MyClass myInstance;
com.mycompany.myproduct.mypackage.MyClass myOtherInstance;
But it could have been
myfeature.MyClass myInstance
myotherfeature.MyClass myInstance;
We could even specify the full package for both.
So, where do those best practices come from?
As it has been said, this convention dates back to the first releases of Java.
Name clashes could be easily solved by qualifying the imported dependency (such as a classpath library) classes with their short packages' hierarchy, emphasizing and keeping cleaner our own code. It is also important to remember we have access to the package-level visibility, which seems overlooked nowdays.
As a commenter points out, this convention was established at the very beginning of Java, to allow a global namespace to be used for all classes.
One thing about Java that influences this -- and is different from TypeScript and JavaScript -- the name of a class and its package (as well as all the names of classes and packages it uses) is fixed at compile time. You can't recombine classes into a different hierarchy without modifying their source code. So it's not as flexible as an interpreted language where you can just move the hierarchy around and change the locations from which you load code.
You can, of course, put everything in your application in the top-level package, for example, and be pretty confident you'll get away with it. You'll be able to do that as long as everyone else follows the existing convention. Once they stop doing that, and libraries start putting classes wherever they want, you'll have collisions, and you'll have to change your application. Or libraries will start colliding with each other, and if you don't have the source, you won't really be able to fix it.
So there are good reasons.
My opinion-based part of this -- sticking with conventions and a language's (or platform's) culture makes sense. Even if the conventions are silly, in our view. There's a place for breaking them but the advantages have to be pretty big. Other developers will be used to the convention, tools will make assumptions about the conventions ... usually it makes sense to go with the flow.
Does it really make sense to use getters and setters for every property in Java? If you understand the domain you're using well, it very well might not. But stop doing it and your code isn't going to make sense to other members of your team, you'll have to continuously revisit the decision as people join, and so forth.
If it's a one-person project and always will be, of course, you can do what you want.
It is much more convenient and cleaner to use a single statement like
import java.awt.*;
than to import a bunch of individual classes
import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...
What is wrong with using a wildcard in the import statement?
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. If you import both using the wildcard method, one of these three things happens:
You have an outright naming conflict between java.awt.Event and com.mycompany.calendar.Event, and so you can't even compile.
You actually manage only to import one (only one of your two imports does .*), but it's the wrong one, and you struggle to figure out why your code is claiming the type is wrong.
When you compile your code, there is no com.mycompany.calendar.Event, but when they later add one, your previously valid code suddenly stops compiling.
The advantage of explicitly listing all imports is that I can tell at a glance which class you meant to use, which simply makes reading the code much easier. If you're just doing a quick one-off thing, there's nothing explicitly wrong, but future maintainers will thank you for your clarity otherwise.
Here's a vote for star imports. An import statement is intended to import a package, not a class. It is much cleaner to import entire packages; the issues identified here (e.g. java.sql.Date vs java.util.Date) are easily remedied by other means, not really addressed by specific imports and certainly do not justify insanely pedantic imports on all classes. There is nothing more disconcerting than opening a source file and having to page through 100 import statements.
Doing specific imports makes refactoring more difficult; if you remove/rename a class, you need to remove all of its specific imports. If you switch an implementation to a different class in the same package, you have to go fix the imports. While these extra steps can be automated, they are really productivity hits for no real gain.
If Eclipse didn't do specific class imports by default, everyone would still be doing star imports. I'm sorry, but there's really no rational justification for doing specific imports.
Here's how to deal with class conflicts:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Please see my article Import on Demand is Evil
In short, the biggest problem is that your code can break when a class is added to a package you import. For example:
import java.awt.*;
import java.util.*;
// ...
List list;
In Java 1.1, this was fine; List was found in java.awt and there was no conflict.
Now suppose you check in your perfectly working code, and a year later someone else brings it out to edit it, and is using Java 1.2.
Java 1.2 added an interface named List to java.util. BOOM! Conflict. The perfectly working code no longer works.
This is an EVIL language feature. There is NO reason that code should stop compiling just because a type is added to a package...
In addition, it makes it difficult for a reader to determine which "Foo" you're using.
It's not bad to use a wild card with a Java import statement.
In Clean Code, Robert C. Martin actually recommends using them to avoid long import lists.
Here is the recommendation:
J1: Avoid Long Import Lists by Using
Wildcards
If you use two or more classes from a
package, then import the whole package
with
import package.*;
Long lists of imports are daunting to
the reader. We don’t want to clutter
up the tops of our modules with 80
lines of imports. Rather we want the
imports to be a concise statement
about which packages we collaborate
with.
Specific imports are hard
dependencies, whereas wildcard imports
are not. If you specifically import a
class, then that class must exist. But
if you import a package with a
wildcard, no particular classes need
to exist. The import statement simply
adds the package to the search path
when hunting for names. So no true
dependency is created by such imports,
and they therefore serve to keep our
modules less coupled.
There are times when the long list of
specific imports can be useful. For
example, if you are dealing with
legacy code and you want to find out
what classes you need to build mocks
and stubs for, you can walk down the
list of specific imports to find out
the true qualified names of all those
classes and then put the appropriate
stubs in place. However, this use for
specific imports is very rare.
Furthermore, most modern IDEs will
allow you to convert the wildcarded
imports to a list of specific imports
with a single command. So even in the
legacy case it’s better to import
wildcards.
Wildcard imports can sometimes cause
name conflicts and ambiguities. Two
classes with the same name, but in
different packages, will need to be
specifically imported, or at least
specifically qualified when used. This
can be a nuisance but is rare enough
that using wildcard imports is still
generally better than specific
imports.
Performance: No impact on performance as byte code is same.
though it will lead to some compile overheads.
Compilation: on my personal machine, Compiling a blank class without importing anything takes 100 ms but same class when import java.* takes 170 ms.
It clutters your namespace, requiring you to fully specify any classnames that are ambiguous. The most common occurence of this is with:
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
It also helps make your dependencies concrete, as all of your dependencies are listed at the top of the file.
It helps to identify classname conflicts: two classes in different packages that have the same name. This can be masked with the * import.
It makes dependencies explicit, so that anyone who has to read your code later knows what you meant to import and what you didn't mean to import.
It can make some compilation faster because the compiler doesn't have to search the whole package to identify depdencies, though this is usually not a huge deal with modern compilers.
The inconvenient aspects of explicit imports are minimized with modern IDEs. Most IDEs allow you to collapse the import section so it's not in the way, automatically populate imports when needed, and automatically identify unused imports to help clean them up.
Most places I've worked that use any significant amount of Java make explicit imports part of the coding standard. I sometimes still use * for quick prototyping and then expand the import lists (some IDEs will do this for you as well) when productizing the code.
I prefer specific imports, because it allows me to see all the external references used in the file without looking at the whole file. (Yes, I know it won't necessarily show fully qualified references. But I avoid them whenever possible.)
In a previous project I found that changing from *-imports to specific imports reduced compilation time by half (from about 10 minutes to about 5 minutes). The *-import makes the compiler search each of the packages listed for a class matching the one you used. While this time can be small, it adds up for large projects.
A side affect of the *-import was that developers would copy and paste common import lines rather than think about what they needed.
In DDD book
In whatever development technology the implementation will be based on, look for ways of minimizing the
work of refactoring MODULES . In Java, there is no escape from importing into individual classes, but you
can at least import entire packages at a time, reflecting the intention that packages are highly cohesive units
while simultaneously reducing the effort of changing package names.
And if it clutters local namespace its not your fault - blame the size of the package.
Here are the few things that I found regarding this topic.
During compilation, the compiler tries to find classes that are used in the code from the .* import and the corresponding byte code will be generated by selecting the used classes from .* import. So the byte code of using .* import or .class names import will be same and the runtime performance will also be the same because of the same byte code.
In each compilation, the compiler has to scan all the classes of .* package to match the classes that are actually used in the code. So, code with .* import takes more time during the compilation process as compared to using .class name imports.
Using .* import helps to make code more cleaner
Using .* import can create ambiguity when we use two classes of the same name from two different packages. Eg, Date is available in both packages.
import java.util.*;
import java.sql.*;
public class DateDemo {
private Date utilDate;
private Date sqlDate;
}
The most important one is that importing java.awt.* can make your program incompatible with a future Java version:
Suppose that you have a class named "ABC", you're using JDK 8 and you import java.util.*. Now, suppose that Java 9 comes out, and it has a new class in package java.util that by coincidence also happens to be called "ABC". Your program now will not compile on Java 9, because the compiler doesn't know if with the name "ABC" you mean your own class or the new class in java.awt.
You won't have that problem when you import only those classes explicitly from java.awt that you actually use.
Resources:
Java Imports
Among all the valid points made on both sides I haven't found my main reason to avoid the wildcard: I like to be able to read the code and know directly what every class is, or if it's definition isn't in the language or the file, where to find it. If more than one package is imported with * I have to go search every one of them to find a class I don't recognize. Readability is supreme, and I agree code should not require an IDE for reading it.
For the record:
When you add an import, you are also indicating your dependencies.
You could see quickly what are the dependencies of files (excluding classes of the same namespace).
There is no runtime impact, as compiler automatically replaces the * with concrete class names. If you decompile the .class file, you would never see import ...*.
C# always uses * (implicitly) as you can only using package name. You can never specify the class name at all. Java introduces the feature after c#. (Java is so tricky in many aspects but it's beyond this topic).
In Intellij Idea when you do "organize imports", it automatically replaces multiple imports of the same package with *. This is a mandantory feature as you can not turn it off (though you can increase the threshold).
The case listed by the accepted reply is not valid. Without * you still got the same issue. You need specify the pakcage name in your code no matter you use * or not.
Forget about cluttered namespaces... And consider the poor soul who has to read and understand your code on GitHub, in vi, Notepad++, or some other non-IDE text editor.
That person has to painstakingly look up every token that comes from one of the wildcards against all the classes and references in each wildcarded scope... just to figure out what in the heck is going on.
If you're writing code for the compiler only - and you know what you're doing - I'm sure there's no problem with wildcards.
But if other people - including future you - want to quickly make sense of a particular code file on one reading, then explicit references help a lot.
Why is using a wild card with a Java import statement bad?
If you're using an IDE (which you should be doing), and there are more code owners than just you, using wildcard imports is bad because it:
conceals information from the rest of the team
provides only false benefits (things which are better-solved using IDE functionality than with wildcard imports) to you as an individual
Most of the "use wildcards" proponents have a focus on the individual: I don't want to maintain the list, I don't want see the clutter, etc. Here are several of the common examples:
maintenance is harder – when you want to introduce a new class into your source code, you have to manually add the import statement
refactoring is more difficult – if code is moved around, then import statements have to be updated
reduce clutter, tidy up file contents – goal here is something along the lines of "removing distractions"
These arguments were more convincing before IDEs did all of that automatically. If you're using a plain text editor instead of an IDE, then these arguments have some merit. But if you're using a plain text editor, you are already subjecting yourself to a number of other much more significant inefficiencies, and managing import statements is just one among many things that you should stop doing by hand. IDEs offer automatic management of imports, powerful refactoring tools, and folding (hiding) of any parts of the code you don't want to see.
For the "avoid wildcards" proponents, there are many examples, but I'll point out only one:
clarity – specifically, when someone new enters the codebase. They will arrive with questions, and continue to discover new questions as they explore the code. For this new code contributor, wildcard import statements do not answer any questions, and at worst can produce confusion, misunderstanding, new questions. In contrast, with explicit imports (and using an IDE) the worst case is neutral: no new info provided; at best, it not only reduces ambiguity but it can also provide answers.
At the end of the day, it helps the entire team to reduce (albeit in a small way) code complexity, to reduce confusion, to add clarity.
Importing all the classes in a package is considered a blind approach. A major reason for this is that it clutters the class namespace and could lead to conflicts between classes in different packages with the same name.
Specifically populating the necessary classes avoids that problem and clearly shows which versions were wanted. This is good for code maintainability.
Is there some sort of tool that you can point at a set of Java classes, and it produces output showing the transitive imports of each class?
I understand that imports are not "transitive" from the point of view of the language itself - i.e. if com.acme.X imports com.acme.Y, and com.acme.Y imports com.acme.Z, that does not mean that you can refer to com.acme.Z within com.acme.X. But that's not what I mean:
Rather, I mean that com.acme.X nonetheless depends upon com.acme.Z (at least under the current implementations of X and Y), and I want to know that fact. In fact I want to know it for a large number of classes, and so I'm hoping that there's a tool do determine it automatically.
Either a standalone tool or an Eclipse plugin or feature would be great.
Thanks in advance.
EDIT to hopefully show what I want this for:
I have a huge monolithic jar that contains many features that are (essentially) completely unrelated. I'd like to break it apart into several smaller, more manageable, and more self-coherent jars.
Unfortunately, I can't do it simply by breaking it up based on packages, because many of the packages themselves are not self-coherent either. That is, for example, there's a "com.acme.utils" package. Two things in that package are probably have nothing in common except for the fact that they're both, in some sense, "utilities". One may be a utility for some particular business function, another may be TCP/IP utilities, another may be a set of string utilities, another may be some completely unrelated business function.
And there are a bunch of packages like this. So when you look at the transitivity of imports from the point of view of packages, they snowball without limit, and so more or less everything in the monolithic jar depends on everything else in the monolithic jar.
So I'd like to start by considering transitivity of imports from the class point of view, rather than the package point of view. That way I should be able to more easily determine what classes need to be reorganized from what existing packages into new, more coherent packages, and then after that I can break the monolithic jar apart by packages / sets of packages.
we're using sonar for software metrics. http://www.sonarsource.org/
We have a number of projects that use the same and/or similar package names. Many or these projects will build jar files that are used by other projects. We have found a number of foo.util foo.db and foo.exceptions where the same class names are being used leading to name space conflicts.
Does anyone know of a tool that will search a set of java code bases and automatically find name space conflicts and ambiguous imports?
It's simpler to fix your names in each individual project.
Really.
You don't need to know all the conflicts. Your package names should be unique in the first place. If they aren't unique, you need to rethink how you're assigning your package names. If they're "flat" (foo.this and foo.that) you need to make them taller and much more specific.
That's why the examples are always org.apache.project.component.lower.level.names.
You should have com.projectX.foo.this and com.projectZ.foo.that to prevent the possibility of duplication.
"But all that recompiling," you say. You'll have to do that anyway. Don't waste a lot of time trying to discover the exact, complete extent. Go with what you know, start fixing things now, and work your way through your code base fixing one thing at a time.
If you can load the projects into Eclipse, the Problems view will give you the conflicts and ambiguous imports. There is also a organize imports wizard that will help with any unnecessary imports.
I agree with S.Lott - you need to find out how this happened in the first place, and make it very painful for the people who did it wrong (i.e. make them go back and fix things). Modern IDEs (Eclipse being one of them) makes this kind of refactoring fairly easy.
The only thing I disagree with is about fixing things as you go. Instead, I strongly recommend that you pay your technical debt on this one now with a solid package name review. A couple of hours (and that's really all it should take) here will save you nightmare debugging down the road.
FYI - it is perfectly legal to have classes in the same package in different source folders (e.g.):
src/com/my/project
test/com/my/project
Trying to differentiate between the above valid folder structure, and the situation you are winding up with is going to be very tough in any automated manner.
It is much more convenient and cleaner to use a single statement like
import java.awt.*;
than to import a bunch of individual classes
import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...
What is wrong with using a wildcard in the import statement?
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. If you import both using the wildcard method, one of these three things happens:
You have an outright naming conflict between java.awt.Event and com.mycompany.calendar.Event, and so you can't even compile.
You actually manage only to import one (only one of your two imports does .*), but it's the wrong one, and you struggle to figure out why your code is claiming the type is wrong.
When you compile your code, there is no com.mycompany.calendar.Event, but when they later add one, your previously valid code suddenly stops compiling.
The advantage of explicitly listing all imports is that I can tell at a glance which class you meant to use, which simply makes reading the code much easier. If you're just doing a quick one-off thing, there's nothing explicitly wrong, but future maintainers will thank you for your clarity otherwise.
Here's a vote for star imports. An import statement is intended to import a package, not a class. It is much cleaner to import entire packages; the issues identified here (e.g. java.sql.Date vs java.util.Date) are easily remedied by other means, not really addressed by specific imports and certainly do not justify insanely pedantic imports on all classes. There is nothing more disconcerting than opening a source file and having to page through 100 import statements.
Doing specific imports makes refactoring more difficult; if you remove/rename a class, you need to remove all of its specific imports. If you switch an implementation to a different class in the same package, you have to go fix the imports. While these extra steps can be automated, they are really productivity hits for no real gain.
If Eclipse didn't do specific class imports by default, everyone would still be doing star imports. I'm sorry, but there's really no rational justification for doing specific imports.
Here's how to deal with class conflicts:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Please see my article Import on Demand is Evil
In short, the biggest problem is that your code can break when a class is added to a package you import. For example:
import java.awt.*;
import java.util.*;
// ...
List list;
In Java 1.1, this was fine; List was found in java.awt and there was no conflict.
Now suppose you check in your perfectly working code, and a year later someone else brings it out to edit it, and is using Java 1.2.
Java 1.2 added an interface named List to java.util. BOOM! Conflict. The perfectly working code no longer works.
This is an EVIL language feature. There is NO reason that code should stop compiling just because a type is added to a package...
In addition, it makes it difficult for a reader to determine which "Foo" you're using.
It's not bad to use a wild card with a Java import statement.
In Clean Code, Robert C. Martin actually recommends using them to avoid long import lists.
Here is the recommendation:
J1: Avoid Long Import Lists by Using
Wildcards
If you use two or more classes from a
package, then import the whole package
with
import package.*;
Long lists of imports are daunting to
the reader. We don’t want to clutter
up the tops of our modules with 80
lines of imports. Rather we want the
imports to be a concise statement
about which packages we collaborate
with.
Specific imports are hard
dependencies, whereas wildcard imports
are not. If you specifically import a
class, then that class must exist. But
if you import a package with a
wildcard, no particular classes need
to exist. The import statement simply
adds the package to the search path
when hunting for names. So no true
dependency is created by such imports,
and they therefore serve to keep our
modules less coupled.
There are times when the long list of
specific imports can be useful. For
example, if you are dealing with
legacy code and you want to find out
what classes you need to build mocks
and stubs for, you can walk down the
list of specific imports to find out
the true qualified names of all those
classes and then put the appropriate
stubs in place. However, this use for
specific imports is very rare.
Furthermore, most modern IDEs will
allow you to convert the wildcarded
imports to a list of specific imports
with a single command. So even in the
legacy case it’s better to import
wildcards.
Wildcard imports can sometimes cause
name conflicts and ambiguities. Two
classes with the same name, but in
different packages, will need to be
specifically imported, or at least
specifically qualified when used. This
can be a nuisance but is rare enough
that using wildcard imports is still
generally better than specific
imports.
Performance: No impact on performance as byte code is same.
though it will lead to some compile overheads.
Compilation: on my personal machine, Compiling a blank class without importing anything takes 100 ms but same class when import java.* takes 170 ms.
It clutters your namespace, requiring you to fully specify any classnames that are ambiguous. The most common occurence of this is with:
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
It also helps make your dependencies concrete, as all of your dependencies are listed at the top of the file.
It helps to identify classname conflicts: two classes in different packages that have the same name. This can be masked with the * import.
It makes dependencies explicit, so that anyone who has to read your code later knows what you meant to import and what you didn't mean to import.
It can make some compilation faster because the compiler doesn't have to search the whole package to identify depdencies, though this is usually not a huge deal with modern compilers.
The inconvenient aspects of explicit imports are minimized with modern IDEs. Most IDEs allow you to collapse the import section so it's not in the way, automatically populate imports when needed, and automatically identify unused imports to help clean them up.
Most places I've worked that use any significant amount of Java make explicit imports part of the coding standard. I sometimes still use * for quick prototyping and then expand the import lists (some IDEs will do this for you as well) when productizing the code.
I prefer specific imports, because it allows me to see all the external references used in the file without looking at the whole file. (Yes, I know it won't necessarily show fully qualified references. But I avoid them whenever possible.)
In a previous project I found that changing from *-imports to specific imports reduced compilation time by half (from about 10 minutes to about 5 minutes). The *-import makes the compiler search each of the packages listed for a class matching the one you used. While this time can be small, it adds up for large projects.
A side affect of the *-import was that developers would copy and paste common import lines rather than think about what they needed.
In DDD book
In whatever development technology the implementation will be based on, look for ways of minimizing the
work of refactoring MODULES . In Java, there is no escape from importing into individual classes, but you
can at least import entire packages at a time, reflecting the intention that packages are highly cohesive units
while simultaneously reducing the effort of changing package names.
And if it clutters local namespace its not your fault - blame the size of the package.
Here are the few things that I found regarding this topic.
During compilation, the compiler tries to find classes that are used in the code from the .* import and the corresponding byte code will be generated by selecting the used classes from .* import. So the byte code of using .* import or .class names import will be same and the runtime performance will also be the same because of the same byte code.
In each compilation, the compiler has to scan all the classes of .* package to match the classes that are actually used in the code. So, code with .* import takes more time during the compilation process as compared to using .class name imports.
Using .* import helps to make code more cleaner
Using .* import can create ambiguity when we use two classes of the same name from two different packages. Eg, Date is available in both packages.
import java.util.*;
import java.sql.*;
public class DateDemo {
private Date utilDate;
private Date sqlDate;
}
The most important one is that importing java.awt.* can make your program incompatible with a future Java version:
Suppose that you have a class named "ABC", you're using JDK 8 and you import java.util.*. Now, suppose that Java 9 comes out, and it has a new class in package java.util that by coincidence also happens to be called "ABC". Your program now will not compile on Java 9, because the compiler doesn't know if with the name "ABC" you mean your own class or the new class in java.awt.
You won't have that problem when you import only those classes explicitly from java.awt that you actually use.
Resources:
Java Imports
Among all the valid points made on both sides I haven't found my main reason to avoid the wildcard: I like to be able to read the code and know directly what every class is, or if it's definition isn't in the language or the file, where to find it. If more than one package is imported with * I have to go search every one of them to find a class I don't recognize. Readability is supreme, and I agree code should not require an IDE for reading it.
For the record:
When you add an import, you are also indicating your dependencies.
You could see quickly what are the dependencies of files (excluding classes of the same namespace).
There is no runtime impact, as compiler automatically replaces the * with concrete class names. If you decompile the .class file, you would never see import ...*.
C# always uses * (implicitly) as you can only using package name. You can never specify the class name at all. Java introduces the feature after c#. (Java is so tricky in many aspects but it's beyond this topic).
In Intellij Idea when you do "organize imports", it automatically replaces multiple imports of the same package with *. This is a mandantory feature as you can not turn it off (though you can increase the threshold).
The case listed by the accepted reply is not valid. Without * you still got the same issue. You need specify the pakcage name in your code no matter you use * or not.
Forget about cluttered namespaces... And consider the poor soul who has to read and understand your code on GitHub, in vi, Notepad++, or some other non-IDE text editor.
That person has to painstakingly look up every token that comes from one of the wildcards against all the classes and references in each wildcarded scope... just to figure out what in the heck is going on.
If you're writing code for the compiler only - and you know what you're doing - I'm sure there's no problem with wildcards.
But if other people - including future you - want to quickly make sense of a particular code file on one reading, then explicit references help a lot.
Why is using a wild card with a Java import statement bad?
If you're using an IDE (which you should be doing), and there are more code owners than just you, using wildcard imports is bad because it:
conceals information from the rest of the team
provides only false benefits (things which are better-solved using IDE functionality than with wildcard imports) to you as an individual
Most of the "use wildcards" proponents have a focus on the individual: I don't want to maintain the list, I don't want see the clutter, etc. Here are several of the common examples:
maintenance is harder – when you want to introduce a new class into your source code, you have to manually add the import statement
refactoring is more difficult – if code is moved around, then import statements have to be updated
reduce clutter, tidy up file contents – goal here is something along the lines of "removing distractions"
These arguments were more convincing before IDEs did all of that automatically. If you're using a plain text editor instead of an IDE, then these arguments have some merit. But if you're using a plain text editor, you are already subjecting yourself to a number of other much more significant inefficiencies, and managing import statements is just one among many things that you should stop doing by hand. IDEs offer automatic management of imports, powerful refactoring tools, and folding (hiding) of any parts of the code you don't want to see.
For the "avoid wildcards" proponents, there are many examples, but I'll point out only one:
clarity – specifically, when someone new enters the codebase. They will arrive with questions, and continue to discover new questions as they explore the code. For this new code contributor, wildcard import statements do not answer any questions, and at worst can produce confusion, misunderstanding, new questions. In contrast, with explicit imports (and using an IDE) the worst case is neutral: no new info provided; at best, it not only reduces ambiguity but it can also provide answers.
At the end of the day, it helps the entire team to reduce (albeit in a small way) code complexity, to reduce confusion, to add clarity.
Importing all the classes in a package is considered a blind approach. A major reason for this is that it clutters the class namespace and could lead to conflicts between classes in different packages with the same name.
Specifically populating the necessary classes avoids that problem and clearly shows which versions were wanted. This is good for code maintainability.