成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【轉(zhuǎn)】Java的package和import機(jī)制

anRui / 3091人閱讀

摘要:比如說,就是復(fù)姓,名字為的類別則是復(fù)姓,名字為的類別。先介紹的機(jī)制基本原則需要將類文件切實(shí)安置到其所歸屬之所對(duì)應(yīng)的相對(duì)路徑下。把源代碼文件,文件和其他文件有條理的進(jìn)行一個(gè)組織,以供來使用??梢允褂猛ㄅ浞?,代表某下所有的,不包括子目錄。

一些人用了一陣子的Java,可是對(duì)于 Java 的 package 跟 import 還是不太了解。很多人以為原始碼 .java 文件中的 import 會(huì)讓編譯器把所 import 的程序通通寫到編譯好的 .class 檔案中,或是認(rèn)為 import 跟 C/C++ 的 #include 相似,實(shí)際上,這是錯(cuò)誤的觀念。

讓我們先了解一下,Java 的 package 到底有何用處。

其實(shí),package 名稱就像是我們的姓,而 class 名稱就像是我們的名字。package 名稱有很多 . 的,就好像是復(fù)姓。比如說 java.lang.String,就是復(fù)姓 java.lang,名字為 String 的類別;java.io.InputStream 則是復(fù)姓java.io,名字為 InputStream 的類別。

Java 會(huì)使用 package 這種機(jī)制的原因也非常明顯,就像我們?nèi)⌒彰粯?,光是一間學(xué)校的同一屆同學(xué)中,就有可能會(huì)出現(xiàn)不少同名的同學(xué),如果不取姓的話,那學(xué)校在處理學(xué)生數(shù)據(jù),或是同學(xué)彼此之間的稱呼,就會(huì)發(fā)生很大的困擾。相同的,全世界的 Java 類別數(shù)量,恐怕比臺(tái)灣人口還多,而且還不斷的在成長當(dāng)中,如果類別不使用套件名稱,那在用到相同名稱的不同類別時(shí),就會(huì)產(chǎn)生極大的困擾。幸運(yùn)的是,Java 的套件名稱我們可以自己取,不像人的姓沒有太大的選擇 ( 所以有很多同名同姓的 ),如果依照 Sun 的規(guī)范來取套件名稱,那理論上不同人所取的套件名稱不會(huì)相同 ( 請(qǐng)參閱 "命名慣例"的相關(guān)文章 ),也就不會(huì)發(fā)生名稱沖突的情況。

可是問題來了,因?yàn)楹芏嗵准拿Q非常的長,在寫程序時(shí),會(huì)多打好多字,花費(fèi)不少時(shí)間,比如說在A.B.C文件下有Point和Circle兩個(gè)類,現(xiàn)在在程序中要調(diào)用:

     A.B.C.Point  P1=new A.B.C.Point();

     A.B.C.Circle  C1=new A.B.C.Circle();

實(shí)在是不美觀又麻煩.于是,Sun 想了一個(gè)辦法,就是 import. 就是在程序一開頭的時(shí)候,說明程序中會(huì)用到那些類的路徑.首先,在檔案開頭寫:

     import A.B.C.Point;

     import A.B.C.Circle;

這兩行說明了類的路徑,所以當(dāng)程序中提到Point就是指A.B.C.Point,而Circle就是指A.B.C.Circle,依此類推。于是原來的程序就變成:

     Point  P1=new Point();

     Circle  C1=new Circle();  

這樣看起來是不是清爽多了呢?如果這些類別用的次數(shù)很多,那就更能體會(huì)到import 的好處了??墒沁@樣還是不夠,因?yàn)閼惺侨说奶煨?,還是會(huì)有人覺得打太多 import 了也很浪費(fèi)時(shí)間,于是 Sun 又提供了一個(gè)方法:

    import A.B.C.*; /*意思就是,等一下程序中提到的沒有姓名的類別,全都包含在A.B.C這個(gè)目錄中。*/

注意點(diǎn):但我們?cè)诔绦蛑薪?jīng)常使用System.out這個(gè)類,為什么沒有import System.out呢,因?yàn)閖ava.lang 這個(gè)套件實(shí)在是太常太常太常用到了,幾乎沒有程序不用它的,所以不管你有沒有寫 import java.lang;,編譯器都會(huì)自動(dòng)幫你補(bǔ)上,也就是說編譯器只要看到?jīng)]有姓的類別,它就會(huì)自動(dòng)去 java.lang 里面找找看,看這個(gè)類別是不是屬于這個(gè)套件的。所以我們就不用特別去import java.lang 了。

為甚么我一開始說 import 跟 #include 不同呢?因?yàn)?import 的功能到此為止,它不像 #include 一樣,會(huì)將檔案內(nèi)容載入進(jìn)來。import 只是請(qǐng)編譯器幫你打字,讓編譯器把沒有姓的類別加上姓,并不會(huì)把別的文件的程式碼寫進(jìn)來。如果你想練習(xí)打字,可以不要使用 import,只要在用到類別的時(shí)候,用它的全部姓名來稱呼它就行了(就像例子一開始那樣),跟使用 import 完全沒有甚么兩樣。

先介紹Java的Package機(jī)制

基本原則:需要將類文件切實(shí)安置到其所歸屬之Package所對(duì)應(yīng)的相對(duì)路徑下。

例如:以下面程序?yàn)槔杭僭O(shè)此Hello.java文件在D:Java下

package  A;
public class Hello{
  public static void main(String args[]){   
     System.out.println("Hello World!");
  }
}

D:Java>javac  Hello.java  此程序可以編譯通過.接著執(zhí)行。
D:Java>java  Hello       但是執(zhí)行時(shí),卻提示以下錯(cuò)誤!
Exception in thread "main" java.lang.NoClassDefFoundError: hello (wrong name: A/Hello)
        at java.lang.ClassLoader.defineClass0(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:537)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)

原因是我們把生成的Hello.class規(guī)定打包在D:JavaA文件中,必須在A文件中才能去運(yùn)行。所以應(yīng)該在D:Java目錄下建立一個(gè)A目錄,然后把把Hello.class放在它下面,執(zhí)行時(shí),可正常通過!
D:Java>java A.hello 就會(huì)輸出:Hello world!

現(xiàn)在介紹Java的import機(jī)制

我們?cè)贒:Java目錄下建立一個(gè)JInTian.java文件,其內(nèi)容如下:

import  A.Hello;
public class JInTian{
   public static void main(String[] args){
       Hello  Hello1=new Hello();
     }
}

D:Java>javac JInTian.java   編譯成功!

D:Java>java  JInTian      運(yùn)行成功!

也就是你在JInTian.class中成功的引用了Hello.class這個(gè)類,是通過import A.Hello來實(shí)現(xiàn)的,如果你沒有這句話,就會(huì)提示不能找到Hello這個(gè)類。

提示1:如果你在D:Java目錄下仍保留一個(gè)Hello.java文件的話,執(zhí)行對(duì)主程序的編譯命令時(shí)仍會(huì)報(bào)錯(cuò)!你自己可以試試呀!
提示2:如果你刪除D:JavaAHello.java文件的話,只留Hello.class文件,執(zhí)行對(duì)主程序的編譯命令時(shí)是可以通過,此時(shí)可以不需要子程序的源代碼。
提出一個(gè)問題:如果把目錄A剪切到其它目錄,如D盤根目錄下,在A目錄如果執(zhí)行編譯和執(zhí)行命令呢?
很明顯,會(huì)報(bào)以下錯(cuò)誤!當(dāng)然了,前提條件是你沒有設(shè)置classpath路徑,其實(shí)只要沒把類搜索路徑設(shè)置到我這個(gè)位置就會(huì)出錯(cuò)的!你試試吧!

由于大家對(duì)package的使用存在太多困惑,我在這里將自己對(duì)于package的使用的領(lǐng)悟進(jìn)行一點(diǎn)總結(jié):

  package中所存放的文件

  所有文件,不過一般分一下就分這三種

  1,java程序源文件,擴(kuò)展名為.java。

  2,編譯好的java類文件,擴(kuò)展名為.class。

  3,其他文件,其他任何文件,也稱為resource

  例如圖片文件,xml文件,mp3文件,avi文件,文本文件……

  package是什么

  package好比java用來組織文件的一種虛擬文件系統(tǒng)。package把源代碼.java文件,.class文件和其他文件有條理的進(jìn)行一個(gè)組織,以供java來使用。package是將文件組織在一顆類似unix,linux文件系統(tǒng)的樹結(jié)構(gòu)里面,它有一個(gè)根"/",然后從根開始有目錄和文件,目錄中也還有文件和目錄。

  package怎么實(shí)現(xiàn)的呢?

  源代碼的要求最嚴(yán)格,而一旦源代碼自己聲明了在哪個(gè)package路徑之下,class也就有了自己在哪個(gè)package下面的信息,就是那句程序開頭的"package xx.xx.xx"。有人問,為什么要有這個(gè)信息,直接放目錄結(jié)構(gòu)里不就好了么?是啊,直接放目錄中確實(shí)可以找到.class和.java,但是如果我要輸出這個(gè).class是屬于哪個(gè)package的,該怎么辦?所以我們需要在.class里面留一個(gè)package的信息。如果我們要區(qū)分同樣名稱為A.class的類怎么辦?所以我們需要在.class里面留一個(gè)package的信息。

  .java文件是一個(gè)獨(dú)立的編譯單元,類似c++里面的cpp文件,但是它不需要.h文件,只要.java就足夠了,一個(gè).java文件里面可以包含一個(gè)public的類,若干package類(package類特征是沒有任何訪問控制修飾),還有內(nèi)隱類的話,則還可以包含若干protected和private的類。每個(gè)類,都會(huì)在編譯的時(shí)候生成一個(gè)獨(dú)立的.class文件,所以.java和.class不是一對(duì)一,而是一對(duì)多的關(guān)系,不過.java和public的類是一對(duì)一的。所有這些.class,都由這個(gè).java開頭的package語句來確定自己在package中的位置。

  package xx.bb.aa;

  說明這個(gè).java編譯單元中的所有類都放到xx.bb.aa這個(gè)package里面。而對(duì)應(yīng)的,必須把這個(gè).java文件放在xx目錄下bb目錄下的aa目錄里面。如果一個(gè).java文件沒有任何package語句,那么這個(gè).java里面的所有類都在package的"/"下面,也稱之為default package??梢钥闯瞿阋话銖娜魏蝚ava教科書上寫的第一個(gè)hello world程序的那個(gè)類是在defaultpackage里面的。有了package語句,情況就復(fù)雜一點(diǎn)了。這個(gè)編譯單元.java必須放在package名對(duì)應(yīng)的目錄之下。而生成的class文件也要放在對(duì)應(yīng)的目錄結(jié)構(gòu)之下才能正常運(yùn)作。

  例如:

    /* A.java */ 
  package aaa.bbb.ccc; 
  public class A{ 
  B b=new B(); 
  } 
  /* B.java*/ 
  package aaa.bbb.ccc; 
  public class B{}

  編譯時(shí)候怎么填參數(shù)呢?我根據(jù)package+文件名的格式來寫,

  javac aaa.bbb.ccc.A.java

  漂亮吧?可惜不工作。非要使用合法的路徑名才行:

  javac aaa/bbb/ccc/A.java

  但是你發(fā)現(xiàn)生成的class丟失了目錄結(jié)構(gòu),直接出現(xiàn)在當(dāng)前目錄下……

  最好的方式是

  javac -d bin aaa/bbb/ccc/A.java

  這樣就會(huì)在當(dāng)前目錄的bin目錄下看到完整的目錄結(jié)構(gòu)以及放置妥當(dāng)?shù)腸lass文件。

  package與classpath不得不說的事

  對(duì)于java來講,所有需要的程序和資源都要以package的形式來組織和讀取。

  那么classpath又是什么呢?

  所有放到設(shè)定到classpath里面的東西就是package所包納的資源。classpath的寫法如同path,只是里面可以寫的一般只有zip文件、jar文件和目錄。多個(gè)元素之間用當(dāng)前系統(tǒng)路徑分隔符間隔開了,linux上分隔符號(hào)是":",windows上是";"。classpath在java里面是被一個(gè)叫做classloader的東西所使用的,classloader顧名思義,就是load class用的,但它也可以load其它在package里面的東西。現(xiàn)在的java里面classloader是有階層關(guān)系的,一般我們所常接觸到的CLASSPATH環(huán)境變量,javac,java的-cp,-classpath參數(shù)所給的classpath信息是被appclassloader所使用的。而appclassloader其實(shí)是第三層的classloader,最高層的classloader叫做bootstrap classloader,它不是java寫的classloader,而是c++寫成的,第二層叫做extclassloader,默認(rèn)包納是jre/lib/ext里面的classes目錄和所有jar文件作為內(nèi)容。第三層才是我們命令行參數(shù),或者不用命令行參數(shù),用系統(tǒng)環(huán)境變量指定classpath的使用者app classloader,這是最基本的java se。如果是java ee,有了服務(wù)器,容器,還有更多層的classloader,他們?cè)赼pp classloader的更下面,例如tomcat的某web應(yīng)用程序的web-inf/lib中的jar,zip和classes目錄,是app之下好幾層的classloader使用的。

  你可以建立自己的classloader,都在app classloader之下,實(shí)際上tomcat本身也是這樣建立classloader的。分層的目的是為了安全,試想你加入搞了一個(gè)classloader,從網(wǎng)絡(luò)上讀取class,而在里面寫上格式化硬盤的代碼,人家一讀運(yùn)行,那不就掛了,所以分層之后,首先從最高層讀,沒有再往下找,找到就不著了。一般java所必須的rt.jar里面的若干class,是在bootstrap classloader啟動(dòng)的時(shí)候讀入的,而jmf使用的幾個(gè)jar,是在ext classloader里面讀入的。也就是說,讀入這些class的時(shí)候,我們的appclassloader還在娘胎里呢,所以你在CLASS PATH中指定rt.jar是完全愚蠢多余的。java絕對(duì)不會(huì)到這里找rt.jar,而bootstrapclassloader如果你不特別要修改,它是常量,不需要你care。

  import干嗎用的?

  import只是一種讓你偷點(diǎn)懶少打字的方法,絕對(duì)不會(huì)影響你的classpath,這點(diǎn)你要好好記住,沒有非用import不可的理由,用了import也不會(huì)起到類似c里面嵌入某文件內(nèi)容的效果,它只是一種省事的辦法。不在classpath中的class,任你再import也無濟(jì)于事。

  如果你不用import,你用ArrayList這個(gè)類,就需要寫

  java.util.ArrayList。

  而用了import java.util.ArrayList;的話

  以后代碼中寫ArrayList就可以了,省事。import可以使用通配符,代表某package下所有的class,不包括子目錄。

  import java.awt.*

  不等于

  import java.awt.*

  import java.awt.event.*

  如果你要簡寫java.awt.event下和java.awt下的類,你不能偷懶,兩個(gè)都要import。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/68720.html

相關(guān)文章

  • 如何讓 node 運(yùn)行 es6 模塊文件,及其原理

    摘要:如何讓運(yùn)行模塊文件,及其原理最新版的支持最新版幾乎所有特性,但有一個(gè)特性卻一直到現(xiàn)在都還沒有支持,那就是從開始定義的模塊化機(jī)制。便是使用這種方式達(dá)到運(yùn)行模塊文件的目的的。 如何讓 node 運(yùn)行 es6 模塊文件,及其原理 最新版的 node 支持最新版 ECMAScript 幾乎所有特性,但有一個(gè)特性卻一直到現(xiàn)在都還沒有支持,那就是從 ES2015 開始定義的模塊化機(jī)制。而現(xiàn)在我們很...

    ytwman 評(píng)論0 收藏0
  • 樂字節(jié)Java|GC垃圾回收機(jī)制、packageimport語句

    摘要:本文接上一篇樂字節(jié)關(guān)鍵字關(guān)鍵字塊。本文是接著講述垃圾回收機(jī)制和語句。一垃圾回收機(jī)制全名垃圾回收機(jī)制程序員無權(quán)調(diào)用垃圾回收器。通知運(yùn)行,但是規(guī)范并不能保證立刻運(yùn)行。若缺省該語句,則指定為無名包。 本文接上一篇:樂字節(jié)Java|this關(guān)鍵字、static關(guān)鍵字、block塊。本文是接著講述JavaGC垃圾回收機(jī)制、package 和 import語句。showImg(https://se...

    xuexiangjys 評(píng)論0 收藏0
  • Java反射機(jī)制詳解

    摘要:反射機(jī)制的應(yīng)用實(shí)例在泛型為的中存放一個(gè)類型的對(duì)象。工廠模式可以參考現(xiàn)在我們利用反射機(jī)制實(shí)現(xiàn)工廠模式,可以在不修改工廠類的情況下添加任意多個(gè)子類。 學(xué)習(xí)交流群:669823128java 反射 定義 功能 示例概要:Java反射機(jī)制詳解| |目錄 1反射機(jī)制是什么 2反射機(jī)制能做什么 3反射機(jī)制的相關(guān)API 通過一個(gè)對(duì)象獲得完整的包名和類名 實(shí)例化Class類對(duì)象 獲取一個(gè)對(duì)象的父類與...

    paraller 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<