1. 程式人生 > >java中import詳解

java中import詳解

前言

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編譯器首選會從無名包中搜索一個型別,然後才是按需型別宣告。如果有命名衝突就會產生問題。