Java包和import語句
包
包是Java語言中有效的管理類的一個機制。不同Java原始檔中可能出現名字相同的類,如果想區分這些類,就需要使用包名。使用包名的目的是有效的區分名字相同的類。
1.包語句
通過關鍵詞package
宣告包語句。package語句需要放在Java原始檔的第一條語句,指明該原始檔定義的類所在的包,即為該原始檔中宣告的類指定包名。
一般格式:
package 包名;//包名是一個合法的識別符號或者若干個識別符號加“.”分隔而成
有的小夥伴可能會有疑問了,在這篇blog之前的blog中的Java程式碼都沒有加上述語句,為什麼還能執行?那是因為我們省略了package語句。如果省略了該語句,原始檔中所定義命名的類被隱含地認為是無名包的一部分,只要這些類的位元組碼被存放在相同的目錄中,那麼他們就屬於同一個包,只是沒有包名罷了。
2.有包名的類的儲存
如果我們顯式地定義了包名,就不能再像之前那樣在隨意的位置存放了,需要遵守一定的規則,否則虛擬機器將無法載入這樣的類。 程式如果使用了包語句,例如:
package x1ao.lin;
那麼在儲存檔案的目錄結構中必須包含如下結構: .../x1ao/lin
(Windows下是\斜槓),並且要將原始檔編譯檔案得到的位元組碼檔案儲存到該目錄(原始檔位置可任意)。
3.執行有包名的主類
如果主類的包名是x1ao.lin,那麼主類的位元組碼一定一定要存放在.../x1ao/lin
目錄中,因此必須到x1ao/lin
的上一層(即x1ao的父目錄)目錄中執行主類。舉個栗子:
x1aolin@x1aolin -E402NA:~/projects$ java x1ao.lin.主類名
Notice: 執行時,必須寫主類的全名。使用包名後主類的全名為“包名.主類名”。
舉個栗子:
xueHao.java : 放在~/projects/x1ao/lin
資料夾下(ubuntu系統)
package x1ao.lin;
public class xueHao{
long xuehao;
xueHao(long xuehao){
this.xuehao = xuehao;
}
void print(){
System.out.print("學號為: "+xuehao);
System. out.print(" xueHao類: package x1ao.lin");
}
}
Exam2.java : 放在~/projects/x1ao/lin
資料夾下(ubuntu系統)
package x1ao.lin;
public class Exam2{
public static void main(String args[]){
xueHao number = new xueHao(2018061366);
number.print();
System.out.println("主類: package x1ao.lin");
}
}
- 編譯。將這兩個檔案放入上面所述的位置後(這只是提供一種可能),然後進入到
/x1ao/lin
的上一層目錄projects中編譯兩個原始檔。如下圖:
//其實只需要執行第一條命令即可,因為他們的原始檔都放在同一目錄中.
//只需編譯主類的原始檔,Java系統會自動地編譯其他的原始檔。
x1aolin@x1aolin-E402NA:~/projects$ javac x1ao/lin/Exam2.java
x1aolin@x1aolin-E402NA:~/projects$ javac x1ao/lin/xueHao.java
- 執行。在
x1ao/
的上一層目錄執行
x1aolin@x1aolin-E402NA:~/projects$ java x1ao.lin.Exam2 //執行命令
學號為: 2018061366 xueHao類: package x1ao.lin //執行結果
主類: package x1ao.lin
注:java語言不允許使用者使用java作為包名或者作為包名的一部分。
import語句
一個類可能需要另一個類宣告的物件作為自己的成員或者作為方法中的區域性變數。如果這兩個類在同一個包中沒問題,但是如果不再同一個包中,就需要import語句來進行引入了。
1.引入類庫中的類
在編寫原始檔的時候,使用者除了自己編寫類外,經常使用Java提供的許多類,這些類可能在不同的包中。為了使用Java提供的類,可以使用import語句引入包中類。import語句可以有多個,位置需要放在package語句(可省略)和原始檔類的定義中間。
- 如果要引入一個包中的所有類,可以用萬用字元“ * ”來代替。例如:
import java.util.*;
- 如果只是使用一個包中的某個類,就可以直接寫明就可以了。例如:
import java.util.Scanner; //用於使用者從控制檯輸入資料
舉個詳細的栗子給大家:
import java.util.Date;
public class Exam3{
public static void main(String args[]){
Date date = new Date();//這是Data類的建構函式
System.out.print("本地機器時間為:"); //不帶空格
System.out.println(date);
}
}
執行結果如下,請大家自行體會:
[email protected]-E402NA:~/桌面/javaExample$ java Exam3
本地機器時間為:Wed Jun 13 13:00:24 CST 2018
下面給出兩點說明:
- java.lang包是Java語言的核心類庫,其中包含了執行Java程式必不可少的系統類,系統會自動引入,不需要再使用import語句。
- 如果使用import語句引入了整個包中的類,可能會增加編譯時間,但是不會影響程式執行時的效能,因為執行和之和位元組碼有關。
2.引入自定義包中的類
方法一: 修改更新classpath,不推薦,此處也不再介紹,對此有興趣的童鞋可自行百度。
方法二: 在使用者程式所在的目錄下建立和包相對應的子目錄結構。
方法二該怎樣理解呢?舉個栗子,假定使用者程式的某個類所在目錄為~/java
,該類想使用import語句x1ao.lin包中的類,那麼根據包名建立如下目錄結構: ~/java/x1ao/lin
即可。emmmm…我個人的理解就是你可以自定義一個目錄,然後一切活動都在這個目錄下進行。如果定義一個包,就將包名形成的目錄放在這個目錄下按照一定的規則進行編譯執行,不太會表達,大家可忽略這句話。
3.使用無包名的類
如果一個類想使用沒有包名的類,只需要將這個無名包的類的位元組碼和當前類儲存在同一目錄下即可。(以前我們也是這麼做的,有沒有想起來呢_)。
4.避免類名混淆
-
如果一個原始檔使用了一個無名包中的A類,同時又用import語句引入了某個有包名的同名類,比如
x1ao.lin
中的A類,這時候就會產生類名的混淆。 -
如果原始檔明確引用該類:
import x1ao.lin.A;
當使用A類時,如果省略包名,那麼原始檔使用的是
x1ao.lin
包中的A類,也就是說原始檔無法使用無名包中的A類。如果想要同時使用,就不能省略包名了。系統會自動檢測,如果檢測到包名,就會自動判定省略包名的程式碼是使用的無名包。 舉個栗子:A x1 = new A(); //無名包建立的物件 x1ao.lin.A x2 = new x1ao.lin.A(); //指定包建立的物件
-
如果原始檔不明確引用該類:
import x1ao.lin.*;
當使用A類時,如果省略包名,那麼原始檔使用的是無名包中的A類,而無法使用指定包中的A類。如果想要同時使用,就不應該省略。
-
如果一個原始檔引入了兩個包中同名的類,那麼在使用類時,不允許 省略包名。