最近,我经常听到“你永远不应该使用通配符导入”这样的陈述。所以我想向社区询问这个问题。是否真的永远不会在Java生产代码中使用通配符导入,无论如何?这条规则有例外吗?我对您的个人经历和意见感兴趣。您是否在生产代码中使用它们并将其推荐给其他人?你如何使用它们 - 你能推荐最好的方法吗?
从Scala的角度来看它也很有趣。 Scala也是如此吗?或者Scala中的通配符导入应仅用于演示幻灯片和SO答案吗?
例如,如果你看一下scalaz page,他们建议使用通配符导入,如:
import scalaz._
import Scalaz._
我认为考虑通常使用通配符导入的隐式转换也很重要。
答案 0 :(得分:14)
在Scala中,通配符导入是必须的,因为许多库希望它们的隐式转换在范围内,但它们并不总是方便地命名。所以,
import collection.JavaConversions._
是个好主意,而
import collection.JavaConversions.{asJavaConcurrentMap,enumerationAsScalaIterator,...}
令人难以置信的尴尬。更好的是,在Scala中,您可以将导入放在任何范围内:
package mypackage {
class MyClass {
def myGraphicalWidgetHandler {
import java.awt._
...
}
...
}
...
}
这确实有助于在整个文件中保持命名空间的混乱。并且您可以有选择地重命名您知道会冲突的部分导入:
import java.awt.{List => AwtList, _}
相比之下,在Java中,您被限制为全局导入范围,并且您无法重命名它们;你也没有隐式转换,所以只需要提取你正在寻找的东西。另一方面,您有强大的IDE支持,可以帮助您找到您正在寻找的类,并为您导入它。所以对于Java来说,有一个合理的论据是你应该让你的IDE接受你需要的东西,而不是你决定抓住所有东西。就个人而言,我仍然发现这太尴尬了,大部分时间只使用通配符导入。
答案 1 :(得分:12)
好吧,通过指定完整的类名,可以消除歧义。因此,当您明确说明要导入哪个类时,更容易理解代码的意图。 Java 1.2也浮现在脑海中:
import java.util.*;
import java.awt.*;
...
List blah;
这在Java 1.1中运行良好。但是,在Java 1.2中,一个List接口被添加到java.util中,以前的代码已经不再适用了。很多开发者都哭了。
答案 2 :(得分:8)
在Java中,使用通配符进行导入或非导入主要是代码可维护性和[不]处理导入歧义的意愿(当两个导入的包具有相同名称的成员时)。另一方面,从意识形态的角度来看,导入整个包(例如,java.sql._
)是非常有意义的是你想要有一致的行为,并避免多行导入相同的包裹。
大部分内容都适用于Scala,区别在于:
import java.io.{File, FileInputStream}
; import java.lang.{Double=>JDouble}
; 所以,总而言之,IMO,Scala中的通配符导入语法只应在这种情况下使用,当您使用特定的库并希望它一致行动时(如果是Scalaz,则全部使用)到位所需的成员,隐式转换等。
答案 3 :(得分:2)
对于Java方面:使用通配符导入绝对没有错!在运行时没有性能缺乏,因为只加载了实际使用的类。
java的导入机制发生在编译时。它唯一用于的是如果你在代码中使用类Date
,那么在同一个包中没有类Date
,导入机制将用于在一个数据库中查找类数据进口报表。
所以它所做的只是“找出你引用的类”。什么都不会改变你的运行时性能。