Import原理,避免误区

        import在java中是非常普遍的关键字,只要是会java基础的人肯定会用,但如果不了解他的其原理,很容易会进入理解的误区。

 

基本概念

        对于每个类,都有一个全名,其中包括两部分:所在的包名和 类名。例如JDK的Map类,全名:java.util.Map,包名:java.util,类名:Map。

        JVM要识别这个类,就是通过全名来查找的,我们来看下面的字节码片段就能明白。  

      【字节码可以通过jclazz来查看http://download.csdn.net/detail/tiwerbao/6497767

SourceCode:

Map map = new HashMap(16);

ByteCode:

0 new java.util.HashMap

3 dup

4 bipush 16 (int)

6 invokespecial

57: Ljava/util/Map;


        其实,我们写Java代码的时候,准确的写法应该是带上类的全名:

	java.util.Map map = new java.util.HashMap(16);

 

        但是这样太累赘了,而且如果多处使用HashMap,还要到处带着这个长长的全名。所以我们通过import来导入我们需要的包,这样我们就只需要直接使用类名就可以了。就像我们的人名一样,我们平时一般直接称呼名字,更加方便,而且也会亲切不少呢。

        所以import的作用相当于C++的命名空间namespace,指定好了用什么“姓”,JVM就知道怎么通过“名”来定为每一个类的“姓名”(全名)了,省了让我们每次都写类的全名,效率还是提高了不少。同时,也解决了不同包的类命名冲突问题。

 

误区-导入

        这里有一个误区,我们平时老说“通过import来导入当前包的外部类”,这里的“导入”很容易让人产生误解,觉得import一个类就会把这个类include进来,或者说加载进来。

        首先要澄清一下,import只是作为一个类的全名补充机制,在编译的时候,编译器会根据import的包来把类名补充成全名,转化为字节码。到此import的职责已经完成,字节码上面就看不到import的影子了,所以根本起不到include引入代码的作用,更别说后面JVM加载执行.class文件了。

        我们可以举个例子:多import一个java.util.Set,看看是否对最终的字节码产生影响。

SourceCode:

	
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        Map map = new HashMap();
    }
}

ByteCode:

1: Class: jscai.Test

8: Methodref: java.lang.Object. (()V)

9: NameAndType: (()V)

14: Utf8: main

15: Utf8: ([Ljava/lang/String;)V

16: Class: java.util.HashMap

18: Methodref: java.util.HashMap. (()V)

19: Utf8: args

20: Utf8: [Ljava/lang/String;

21: Utf8: map

22: Utf8: Ljava/util/Map;

23: Utf8: SourceFile

24: Utf8: Test.java

 

        可以看出来,字节码中完全没有java.util.Set的影子,说明import只是作为一个编译器生成字节码的命名过度工具,如果代码中没有使用到该类,即使import也不会对字节码产生影响,所以对后面JVM的执行也是没有影响的。

        同时,一些java的编码规范(如Sun、CheckStyle)都要求删除java文件中多余的import语句(见UnusedImports规则),又是为什么呢?

        原来,编译器根据import拼装类全名的时候,会去遍历import导入的包,所以多余的import会影响编译的效率。同时,多余的import也会提高类名冲突发生的概率(引入的姓越多,就越容易撞名),而且还违背了clean code的原则。

        所以,还是锦上添花,把多余的import干掉吧。而且在eclipse中,只要轻轻一按[ctrl+shift+O],就能把多余的import清空,以及补全缺少的import。

        同理,在import的时候,最好使用“单类型导入(single-type-import)”,直接import你需要的类,而不是导入整个包,这样也能减少编译器多余的查找,节省性能。

 

参考文章:http://www.cnblogs.com/yqskj/articles/2097836.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值