Should Wildcard Import Be Avoided

Why is using a wild card with a Java import statement bad?

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:

  1. You have an outright naming conflict between java.awt.Event and com.mycompany.calendar.Event, and so you can't even compile.
  2. 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.
  3. 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 that 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.

Should wildcard import be avoided?

The answer to your question's title is "yes": I recommend never using from ... import *, and I discussed the reasons in another very recent answer. Briefly, qualified names are good, barenames are very limited, so the "third option" is optimal (as you'll be using qualified names, not barenames) among those you present.

(Advantages of qualified names wrt barenames include ease of faking/mocking for testing purposes, reduced to nullified risk of unnoticed errors induced by accidental rebinding, ability to "semi-fake" the top name in a "tracing class" for the purpose of logging exactly what you're using and easing such activities as profiling, and so forth -- disadvantages, just about none... see also the last-but-not-least koan in the Zen of Python, import this at the interactive interpreter prompt).

Equally good, if you grudge the 7 extra characters to say QtCore.whatever, is to abbreviate -- from PyQt4 import QtCore as Cr and from PyQt4 import QtGi as Gu (then use Cr.blah and Gu.zorp) or the like. Like all abbreviations, it's a style tradeoff between conciseness and clarity (would you rather name a variable count_of_all_widgets_in_the_inventory, num_widgets, or x? often the middle choice would be best, but not always;-).

BTW, I would not use more than one as clause in a single from or import statement (could be confusing), I'd rather have multiple statements (also easier to debug if any import is giving problem, to edit if you change your imports in the future, ...).

Performance difference between a wild card import and the required class import

At runtime 0.

Both generate the same byte code

IntelliJ: Never use wildcard imports

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.

Click on the Settings "wrench" icon on the toolbar, open "Imports" under "Code Style", and check the "Use single class import" selection. You can also completely remove entries under "Packages to use import with *", or specify a threshold value that only uses the "*" when the individual classes from a package exceeds that threshold.

Update: in IDEA 13 "Use single class import" does not prevent wildcard imports. The solution is to go to Preferences ( + , on macOS / Ctrl + Alt + S on Windows and Linux) > Editor > Code Style > Java > Imports tab set Class count to use import with '*' and Names count to use static import with '*' to a higher value. Any value over 99 seems to work fine.

What is the reason for using a wildcard import?

According to [Python.Docs]: Modules - More on Modules (emphasis is mine):

There is even a variant to import all names that a module defines:

>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

This imports all names except those beginning with an underscore (_). In most cases Python programmers do not use this facility since it introduces an unknown set of names into the interpreter, possibly hiding some things you have already defined.

Note that in general the practice of importing * from a module or package is frowned upon, since it often causes poorly readable code. However, it is okay to use it to save typing in interactive sessions.

So, it means: importing all (check the above page for the __all__ variable meaning) symbols exported by a module / package into the current namespace.

Generally (as the above states), it's used when one is in the console and wants to save time by not importing everything needed, "manually".
It's also used by some who don't know what to import (so they import everything, since they don't really know what they're doing - there are exceptions of course, but those are rare).

Anyway, probably this is the most eloquent example (as it only relies on Python): illustrating its pitfalls:

>>> with open("out.txt", "w") as f:
... f.write("DON'T USE wildcard imports!")
...
27
>>>
>>> from os import *
>>>
>>> with open("out.txt", "w") as f:
... f.write("USING wildcard imports ...")
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required (got type str)

The wildcard import shadows:

  • [Python.Docs]: Built-in Functions - open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

by:

  • [Python.Docs]: os.open(path, flags, mode=0o777, *, dir_fd=None)

Things can get even messier when dealing with 3rd-party modules (where the collision hit chance can grow exponentially).

Wildcard or asterisk (*) vs named or selective import es6 javascript

If you use webpack with the dead code elimination provided by the new uglify, or rollupjs with tree-shaking, then the unused imports will be stripped.

I partially agree with the airbnb styleguide to not to use wildcard imports, although javascripts wildcard imports do not suffer from the same diseases as for example pythons or javas wildcard imports, namely it does not pollute the scope with variable names defined in other modules (you can only access them by moduleB.foo, not foo when using import * as moduleB from ...).

About the article on testing: I kindof understand the concerns, but I see nothing that cannot be solved there. You can mock the imports themselves with some custom module loader (a custom amd module loader is literally 15 lines of code), so you dont have to mess with the local scope of the tested module.

Is it a bad practice to import all the sub classes of a class at a time?

To be specific, what exactly is the difference between import java.applet.*; & import java.*;

The first import makes all types (classes, interfaces, enums) from the java.applet package visible to the compiler, while the second makes all types from the java package visible.

Note that there is no "subclass" relationship between packages - packages make up a package hierarchy, but not a class hierarchy. With a wildcard import (import package.*), all types from one single package are imported, not from a whole package hierarchy. In particular, import java.* does not import java.applet or any other package below java in addition.

In practice, by the way, you should avoid wildcard imports at all as they pollute your name space and might cause naming conflicts when identical type names exist in different packages. Most IDEs today organize the imports (semi-)automatically, so there is no need to use the wildcard import.



Related Topics



Leave a reply



Submit