简体   繁体   中英

Wildcard imports usage in Java and Scala

Recently I have heard statements like "you should never use wildcard imports" too often. So I want to ask community about this. Should wildcard imports really never ever be used in Java production code, no matter what? Are there exceptions to this rule? I interested in your personal experience and opinion. Do you use them in your production code and would you recommend it to others? How do you use them - can you recommend the best way to make it.

It also interesting to look at it from Scala perspective. Is the same applies to Scala? Or wildcard imports in Scala should be only used in presentation slides and SO answers?

If you will look at scalaz page , for example, they recommend usage of wildcard imports like:

import scalaz._
import Scalaz._   

I think it also important to consider implicit conversions that are normally imported with wildcards.

In Scala, wildcard imports are a must, since many libraries expect their implicit conversions to be in scope, but they're not always conveniently named. So,

import collection.JavaConversions._

is a great idea, whereas

import collection.JavaConversions.{asJavaConcurrentMap,enumerationAsScalaIterator,...}

is incredibly awkward. Better yet, in Scala you can put your imports in any scope:

package mypackage {
  class MyClass {
    def myGraphicalWidgetHandler {
      import java.awt._
      ...
    }
    ...
  }
  ...
}

which really helps keep the namespace clutter down throughout the whole file. And you can selectively rename parts of the import that you know will conflict:

import java.awt.{List => AwtList, _}

In contrast, in Java, you're restricted to global scope for imports, and you can't rename them; you also don't have implicit conversions, so it's okay to only pull in those things that you're looking for. On the other hand, you have powerful IDE support that will help find the class that you're looking for and import just it for you. So for Java, there's a reasonable argument to be made that you should let your IDE pull in just what you need rather than you deciding to grab everything. Personally, I still find this too awkward and just use wildcard imports most of the time.

Well, by specifiying full classnames you remove ambiguity. So, when you explicitly state which class to import it's a lot easier to understand the intention of the code. Java 1.2 also comes to mind:

import java.util.*;
import java.awt.*;

...
List blah;

This worked fine in Java 1.1. However, in Java 1.2 a List interface was added to java.util, and the code that used to be fine didn't work anymore. Lots of developers cried.

In Java, using wildcards for import or not is mostly a question of code maintainability and [un-]willingness to deal with import ambiguities (when two imported packages have members with the same names). On the other hand, from the ideology perspective, it's makes a lot of sense to import the entire pack (say, java.sql._ ) is you want to have a consistent behavior, and avoid multiple lines of imports from the same package.

The most of it is true to Scala, with the difference that:

  1. If you want to import multiple members from the same class not polluting the code, and, at the same time, avoid possible ambiguities, Scala offers a special syntax for that: import java.io.{File, FileInputStream} ;
  2. In Scala you can give aliases to the imported members, for dealing with ambiguities: import java.lang.{Double=>JDouble} ;
  3. As you correctly mentioned, using a wildcard import you add implicits to the context, which may lead to another level of ambiguities (so that's another reason to think twice);

So, all in all, IMO, wildcard import syntax in Scala should be used only in the case, when you're working with a specific library and want it to act consistently (in case of Scalaz, to have all the required members, implicit conversion, etc. in place).

For the Java side: There is absolutely nothing wrong with using wildcard imports! There is no performance lack at runtime because only the Classes which are actually be used are loaded.

The import mechanism of java takes place at compile time. The only thing it is used for is if you use the Class Date for example in your code ant there is no class Date in the same package the import mechanism will be used to find the class Data in one of the import statements.

So all it does is "finding out what class you are referencing to". Nothing what could change your runtime performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM