java中import,package的用法

有些人寫了一陣子 Java,但是對於 Java 的 package 跟 import 仍是不 
太瞭解不少人以為原始碼 .java 檔案中的 import 會讓編譯器把所 import 
的程式統統寫到編譯好的 .class 檔案中,或是認為 import 跟 C/C++ 的 
#include 類似,實際上,這是錯誤的觀念。
java

讓咱們先了解一下,Java 的 package 到底有何用處。程序員

其實,package 名稱就像是咱們的姓,而 class 名稱就像是咱們的名字 
。package 名稱有不少 . 的,就好像是複姓。好比說 java.lang.String,就 
是複姓 java.lang,名字為 String 的類別;java.io.InputStream 則是複姓 
java.io,名字為 InputStream 的類別。
ide

Java 會使用 package 這種機制的緣由也很是明顯,就像咱們取姓名同樣 
,光是一間學校的同一屆同窗中,就有可能會出現很多同名的同窗,若是不取 
姓的話,那學校在處理學生資料,或是同窗彼此之間的稱呼,就會發生很大的 
困擾。相同的,全世界的 Java 類別數量,恐怕比臺灣人口還多,並且還不斷 
的在成長當中,若是類別不使用套件名稱,那在用到相同名稱的不一樣類別時, 
就會產生極大的困擾。幸運的是,Java 的套件名稱咱們能夠本身取,不像人 
的姓沒有太大的選擇 ( 因此有不少同名同姓的 ),若是依照 Sun 的規範來取
套件名稱,那理論上不一樣人所取的套件名稱不會相同 ( 請參閱 "命名慣例" 
的相關文章 ),也就不會發生名稱衝突的狀況。
spa

但是問題來了,因為不少套件的名稱很是的長,在寫程式時,會多打好多 
字,花費很多時間,好比說:
orm


      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;
it

 


這幾行說明了這四個姓名的類別,在程式中只用他的名字來稱呼,因此當程式 
中提到 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也導入,這但是在當前包中啊! 

相關文章
相關標籤/搜索