前言
import與package機制相關,這里先從package入手,再講述import以及static import的作用。
package
package名稱就像是我們的姓,而class名稱就像是我們的名字 。package和package的附屬關系用”.”來連接,這就像是復姓。比如說 java.lang.String就是復姓 java.lang,名字為 String 的類別;java.io.InputStream 則是復姓 java.io,名字為 InputStream的類別。
import
import就是在java文件開頭的地方,先說明會用到那些類別。
接着我們就能在代碼中只用類名指定某個類,也就是只稱呼名字,不稱呼他的姓。
首先,在程序開頭寫:
import java.lang.System;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
於是我們就可以在程序中這樣寫到:
InputStream = System.in; InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr);
一個java文件就像一個大房間,我們在門口寫着在房間里面的class的姓和名字,所以在房間里面提到某個class就直接用他的名字就可以。例如:
System 就是指 java.lang.System,而 InputStream 就是指 java.io.InputStream。
但是如果一個java文件里面有多個同個“姓”,即包名相同的類(例如上面的InputStream,InputStreamReader,BufferedReader都是java.io中的類),我們一一寫出顯得比較繁雜,所以Sun就讓我們可以使用
1 import java.lang.*; 2 import java.io.*;
表示文件里面說到的類不是java.lang包的就是java.io包的。編譯器會幫我們選擇與類名對應的包。
但是我們不可以寫成:
1 import java.*;
因為那些類別是姓 java.io 而不是姓 java。就像姓『諸葛』的人應該不會喜歡你稱他為『諸』 先生吧。
這樣寫的話只會將java包下的類聲明,而不不會聲明子包的任何類。
這里注意,java.lang包里面的類實在是太常太常太常用到了,幾乎沒有類不用它的, 所以不管你有沒有寫 import java.lang,編譯器都會自動幫你補上,也就是說編譯器只要看到沒有姓的類別,它就會自動去lang包里面查找。所以我們就不用特別去 import java.lang了。
import的兩種導入聲明
- 單類型導入(single-type-import)
(例:import java.util.ArrayList; ) - 按需類型導入(type-import-on-demand)
(例:import java.util.*;)
static import靜態導入
static import和import其中一個不一致的地方就是static import導入的是靜態成員,而import導入的是類或接口類型。
實例:
如下是一個有靜態變量和靜態方法的類
1 package com.assignment.test; 2 3 public class staticFieldsClass { 4 static int staticNoPublicField = 0; 5 public static int staticField = 1; 6 public static void staticFunction(){} 7 }
平時我們使用這些靜態成員是用類名.靜態成員的形式使用,即staticFieldsClass.staticField或者staticFieldsClass.staticFunction()。
現在用static import的方式:
1 //**精准導入** 2 //直接導入具體的靜態變量、常量、方法方法,注意導入方法直接寫方法名不需要括號。 3 import static com.assignment.test.StaticFieldsClass.staticField; 4 import static com.assignment.test.StaticFieldsClass.staticFunction; 5 6 //或者使用如下形式: 7 //**按需導入**不必逐一指出靜態成員名稱的導入方式 8 //import static com.assignment.test.StaticFieldsClass.*; 9 10 public class StaticTest { 11 public static void main(String[] args) { 12 //這里直接寫靜態成員而不需要通過類名調用 13 System.out.println(staticField); 14 staticFunction(); 15 } 16 }
按需導入機制
使用按需導入聲明是否會降低Java代碼的執行效率?
絕對不會!
一、import的按需導入
mport java.util.*; public class NeedImportTest { public static void main(String[] args) { ArrayList tList = new ArrayList(); } }
編譯之后的class文件 :
//import java.util.*被替換成import java.util.ArrayList
//即按需導入編譯過程會替換成單類型導入。
import java.util.ArrayList;
public class NeedImportTest {
public static void main(String[] args) {
new ArrayList();
}
}
這是否意味着你總是可以使用按需導入聲明?
是,也不是!
在類似Demo的非正式開發中使用按需導入聲明顯得很有用。
然而,有這四個理由讓你可以放棄這種聲明:
編譯速度:在一個很大的項目中,它們會極大的影響編譯速度.但在小型項目中使用在編譯時間上可以忽略不計。
命名沖突:解決避免命名沖突問題的答案就是使用全名。而按需導入恰恰就是使用導入聲明初衷的否定。
說明問題:畢竟高級語言的代碼是給人看的,按需導入看不出使用到的具體類型。
無名包問題:如果在編譯單元的頂部沒有包聲明,Java編譯器首選會從無名包中搜索一個類型,然后才是按需類型聲明。如果有命名沖突就會產生問題。