Java中import及package的用法
有些人写了一阵子 Java,可是对於 Java 的 package 跟 import 还是不
太了解很多人以為原始码 .java 档案中的 import 会让编译器把所 import
的程式通通写到编译好的 .class 档案中,或是认為 import 跟 C/C++ 的
#include 相似,实际上,这是错误的观念。
让我们先了解一下,Java 的 package 到底有何用处。
其实,package 名称就像是我们的姓,而 class 名称就像是我们的名字
。package 名称有很多 . 的,就好像是复姓。比如说 java.lang.String,就
是复姓 java.lang,名字為 String 的类别;java.io.InputStream 则是复姓
java.io,名字為 InputStream 的类别。
Java 会使用 package 这种机制的原因也非常明显,就像我们取姓名一样
,光是一间学校的同一届同学中,就有可能会出现不少同名的同学,如果不取
姓的话,那学校在处理学生资料,或是同学彼此之间的称呼,就会发生很大的
困扰。相同的,全世界的 Java 类别数量,恐怕比台湾人口还多,而且还不断
的在成长当中,如果类别不使用套件名称,那在用到相同名称的不同类别时,
就会產生极大的困扰。幸运的是,Java 的套件名称我们可以自己取,不像人
的姓没有太大的选择 ( 所以有很多同名同姓的 ),如果依照 Sun 的规范来取
套件名称,那理论上不同人所取的套件名称不会相同 ( 请参阅 "命名惯例"
的相关文章 ),也就不会发生名称衝突的情况。
可是问题来了,因為很多套件的名称非常的长,在写程式时,会多打好多
字,花费不少时间,比如说:
java.io.InputStream is = java.lang.System.in;
java.io.InputStreamReader isr= new java.io.InputStreamReader(is);
java.io.BufferedReader br = new java.io.BufferedReader(isr);
实在是不美观又麻烦。於是,Sun 想了一个办法,就是 import。
这个 import 就是在程式一开头的时候,先说明程式中会用到那些类别的简称,也就是只称呼名字,不称呼他的姓。首先,在档案开头写:
import java.lang.System;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
这几行说明了这四个姓名的类别,在程式中只用他的名字来称呼,所以当程式
中提到 System 就是指 java.lang.System,而 InputStream 就是指
java.io.InputStream,依此类推。於是原来的程式就变成:
InputStream = System.in;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
这样看起来是不是清爽多了呢?如果这些类别用的次数很多,那就更能体会到
import 的好处了。可是这样还是不够,因為懒是人的天性,还是会有人觉得
打太多 import 了也很浪费时间,於是 Sun 又提供了一个方法:
import java.lang.*;
import java.io.*;
意思就是,等一下程式中提到的没有姓名的类别,不是姓 java.lang,就是姓
java.io,如果这两个裡面有同样名字的类别,而不幸的你又只用名字称呼这
个类别,那编译器仍然会跟你抱怨,因為它还是不知道你说的这个类别指那一
个姓的类别。那可不可以再懒一点呢,只写:
import java.*;
歷史告诉我们,人可以懒,但不能太懒,这样是不行的。因為那些类别是姓
java.io 而不是姓 java。就像姓『诸葛』的人应该不会喜欢你称他為『诸』
先生吧。
為甚麼我一开始说 import 跟 #include 不同呢?因為 import 的功能
到此為止,它不像 #include 一样,会将档案内容载入进来。import 只是请
编译器帮你打字,让编译器把没有姓的类别加上姓,并不会把别的档案的程
式码写进来。如果你想练习打字,可以不要使用 import,只要在用到类别的
时候,用它的全部姓名来称呼它就行了(就像例子一开始那样),跟使用
import 完全没有甚麼两样。
另外,虽然人不可以太懒,但是 Sun 还是帮我们多偷了一点懒。因為
java.lang 这个套件实在是太常太常太常用到了,几乎没有程式不用它的,
所以不管你有没有写 import java.lang;,编译器都会自动帮你补上,也就
是说编译器只要看到没有姓的类别,它就会自动去 java.lang 裡面找找看,
看这个类别是不是属於这个套件的。所以我们就不用特别去
import java.lang 了。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
import导入声明可分为两中:
1>单类型导入(single-type-import)
例:import java.util.ArrayList;
2>按需类型导入(type-import-on-demand)
例:import java.util.*;
以这样两种方式导入包中的任何一个public的类和接口(只有public类和接口才能被导入)
*导入声明仅导入类型而不导入子包;这就是为什么称它们为单类型导入和按需类型导入声明的原因.
*导入的类或接口的简名(simple name)具有编译单元作用域.这表示该类型简名可以在导入语句所在的编译单元的任何地方使用.这并不意味着你可以使用该类型所有成员的简名,而只能使用类型自身的简名.
例如: java.lang包中的public类都是自动导入的,包括Math和System类.但是,你不能使用简名PI()和gc(),而必须使用Math.PI()和System.gc().你不需要键入的是java.lang.Math.PI()和java.lang.System.gc().
程序员有时会导入当前包或java.lang包,这是不需要的,因为当前包的成员本身就在作用域内,而java.lang包是自动导入的.java编译器会忽略这些冗余导入声明(redundant import declarations).即使像这样
import java.util.ArrayList;
import java.util.*;
多次导入,也可编译通过.编译器会将冗余导入声明忽略.
使用按需导入声明是否会降低Java代码的执行效率?绝对不会!
Java编译器产生的类文件仅包含编译单元实际使用到的类或接口的符号引用.
这是否意味着你总是可以使用按需导入声明?是,也不是!
在类似Demo的非正式开发中使用按需导入声明显得很有用.
然而,有这四个理由让你可以放弃这种声明:
1>编译速度:在一个很大的项目中,它们会极大的影响编译速度.但在小型项目中使用在编译时间上可以忽略不计.
2>命名冲突:解决避免命名冲突问题的答案就是使用全名.而按需导入恰恰就是使用导入声明初衷的否定.
3>说明问题:全名的使用是自说性的.毕竟高级语言的代码是给人看的.
4>无名包问题:如果在编译单元的顶部没有包声明,Java编译器首选会从无名包中搜索一个类型,然后才是按需类型声明.如果有命名冲突就会产生问题.
Sun的工程师一般不使用按需类型导入声明.这你可以在他们的代码中找到:
在java.util.Properties类中的导入声明:
import java.io.IOException;
import java.io.printStream;
import java.io.printWrite;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.Hashtable;
你可以看到有趣的是,她连java.util.Hashtable也导入,这可是在当前包中啊!
参考资料:http://xgtian.blog.51cto.com/3844449/737269
Java中import及package的用法的更多相关文章
- Java中枚举的写法和用法
在公司代码中,用了一大堆的枚举,看得我好懵逼.下面开始看看枚举怎么写和怎么用. 一.枚举的写法 关于枚举的写法,网上好多这方面的知识.这里直接贴一个我自己写的枚举类的代 ...
- [转载]java中import作用详解
[转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...
- java中不带package和带package的编译运行方式
Java中不带package的程序和带package的程序编译的方式是不同的. 一.不带package的程序建立个HelloWorld.java的文件,放入C:\,内容如下:public class ...
- JAVA中字符串函数subString的用法小结
本篇文章主要是对JAVA中字符串函数subString的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 String str; str=str.substring(int begi ...
- 【Java学习笔记之二十九】Java中的"equals"和"=="的用法及区别
Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: String str1 = new String(" ...
- java中 this 的三种用法
Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...
- Java中try,catch,finally的用法
Java中try,catch,finally的用法,以前感觉还算熟悉,但看到一篇博文才有更深点的理解,总结网友博客如下. Java异常处理的组合方式: 1.try+catch 运行流程:运行到try ...
- java中静态代码块的用法 static用法详解和static静态导入
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- java中import详解
前言 import与package机制相关,这里先从package入手,再讲述import以及static import的作用. package package名称就像是我们的姓,而class名称就像 ...
随机推荐
- ios学习——键盘的收起
在开发过程中,我们经常会用到UITextField.UITextView等文本框,然后这些文本框在点击之后会自动成为第一响应者(FirstResponder),并自动弹出软键盘.然而,没有自动定义好的 ...
- iOS动态性 运行时runtime初探(强制获取并修改私有变量,强制增加及修改私有方法等)
借助前辈的力量综合一下资料. OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是 ...
- linux下PHP后台配置极光推送问题
一.composer.json配置注意空格 按照极光推送官网所述,在composer.json下写入: "require": { "jpush/jpush": ...
- Bash shell命令记录和CentOS的一些技巧
①CentOS的实用技巧: 一.按下ctrl+alt+F2可由图形界面切换至命令行(shell窗口),按下ctrl+alt+F1可由命令行切换至图形界面(前提是安装CentOS时软件选择项选择安装了图 ...
- Spring+MVC+Mybatis整合
本文是对慕课网上"搞定SSM开发"路径的系列课程的总结,详细的项目文档和课程总结放在github上了.点击查看 什么是秒杀业务 网站售卖某产品时,规定在某个日期开始售卖限量的产品, ...
- Java 伙伴系统(模拟)
参考:https://labrick.cc/2015/10/12/buddy-system-algorithm/ 代码过烂 不宜参考. output: [operating.entity.Heap@4 ...
- 1-MySQL数据库(android连接MySQL数据库)
很好的链接 http://www.cnblogs.com/best/p/6517755.html 一个小时学会MySQL数据库 http://www.cnblogs.com/klguang/p/47 ...
- 51Nod1203 2012集训队答辩 JZPLCM
A1339. JZPLCM(顾昱洲) 时间限制:3.0s 内存限制:256.0MB 试题来源 2012中国国家集训队命题答辩 问题描述 给定一长度为n的正整数序列a,有q次询问,每次询问一段区 ...
- js-使用JavaScript、jQuery两种方式实现全选/全不选
html代码 <input type='checkbox' value="10" name="frust"/>苹果10元 <br/> & ...
- 使用linux perf工具生成java程序火焰图
pre.cjk { font-family: "Nimbus Mono L", monospace } p { margin-bottom: 0.1in; line-height: ...