當我#include或import的時候,我到底幹了什麼?

C語言中的#include

學習C語言的時候,你們都寫過這麼一個hello worldjava

#include <stdio.h>
int main()
{
    printf("hello, world");
    return 0;
}

但若是沒有第一句#include <stdio.h>,編譯是通不過的
由於printf這個函數沒有被聲明,由於C語言要求,函數必須先聲明再調用函數

事實上,#include <stdio.h>所作的僅僅是把stdio.h這個文件給包括進來了,就像你找到stdio.h文件,並把全部內容複製到main函數的前面,效果是徹底同樣的。學習

stdio.h包括的是對C語言標準庫中一系列函數的聲明(固然也有printf的),一般它在你的編譯器安裝位置的include目錄下。編譯器是會默認的去這個目錄尋找你include的文件的。code

因此,#include <stdio.h>以後,程序就能編譯經過了。而printf的實如今C語言標準庫libc.a中,標準庫的實現是會被編譯器自動連接進你的程序的。orm

知道了原理,咱們有另外一種方式去成功的調用printf函數,那就是本身聲明它。編譯器

int printf(const char *format, ...);
int main()
{
    printf("hello, world");
    return 0;
}

相信我,這個程序也是能編譯成功並且輸出正確結果的,由於第一句話和#include <stdio.h>的目的是同樣的,只不過是僅僅聲明瞭其中一個函數而已。io

Java中的import

若是你覺得import#include同樣是把整個文件包含進來,那就錯了。事實上,import的做用是在寫程序的時候,不用把類或者變量的長長的全名打出來。編譯

說到這裏,不得不說一下Java組織源代碼的方式。
Java的每一個public的類都是一個文件,它位於某個package之中,而package則是許多文件夾構成的一個路徑。form

以下圖,假設個人Java工程的源代碼都在src文件夾下,cc.chenjr.mypackage就是一個package(注意它實際上就是文件夾),MyClass是這個package下的一個類。class

src
└── cc
    └── chenjr
        └── mypackage
            └── MyClass.java

爲了不與其餘package下的MyClass類混淆,它有一個全名是cc.chenjr.mypackage.MyClass。好比System的全名是java.lang.System。咱們不用去import java.lang.System是由於編譯器幫咱們作了這件事。

那在別的文件中要用cc.chenjr.mypackage.MyClass的時候,打全名實在太麻煩,因此咱們就告訴編譯器,我這個文件裏的MyClass就是cc.chenjr.mypackage.MyClass而不是其餘的MyClass。這就是import的做用了。

一樣,每一個.java文件的第一句package cc.chenjr.mypackage;是告訴編譯器,我這個類是在這個package下面的。若是這個類的文件被移動到別的文件夾下,是編譯不了的。

固然,若是咱們非要用到兩個MyClass,其中有一個就不得不打全名了,好比這樣,假設我本身有和Java庫中名字衝突的類並import了它們,我想用Java的標準庫的類就只能打全名了。

package cc.chenjr.mypackage;
import cc.chenjr.mypackage.List;
import cc.chenjr.mypackage.ArrayList;

public class Test {
    public static void main(String[] args) {
        java.util.List list = new java.util.ArrayList();
    }
}
相關文章
相關標籤/搜索