www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]一、super()?方法的用法及作用? 有如下Java類: ????public?class?Bird{? ????private?String?name;? ????public?Bird()?

一、super()?方法的用法及作用?

有如下Java類:

????public?class?Bird{?
????private?String?name;?
????public?Bird()?{?}?
????public?Bird(String?name){?this.name?=?name;?}?
????public?void?walk()?{?System.out.println(“走路”);?}?
????public?String?getName(){?return?name;?}?
????public?void?setName(String?name){?this.name?=?name;?}?
????}?

另有一個(gè)類Chicken繼承上邊的Bird類;

????public?class?Chicken?extends?Bird{?
????private?String?crest;?
????public?Chicken(){?super();?}?
????public?Chicken(String?name,String?crest)?{?
????super(name);?
????this.name?=?name;?}?
????………….?
????}?

在第二個(gè)自定義的類Chicken中,super()方法一共出現(xiàn)了兩次,分別是super()和super(name),請(qǐng)問(wèn)super()?是什么含義,放在這里又作何解釋?

參考答案:

1.子類的構(gòu)造過(guò)程中必須調(diào)用父類的構(gòu)造方法。

2.子類可在自己的構(gòu)造方法中使用super()來(lái)調(diào)用父類的構(gòu)造方法。

(1)使用this來(lái)調(diào)用本類的另外的構(gòu)造方法。

(2)如果調(diào)用super必須寫在子類構(gòu)造方法的第一行。

3.如果子類的構(gòu)造方法中沒(méi)有顯示的調(diào)用父類的構(gòu)造方法,則系統(tǒng)默認(rèn)的調(diào)用父類的無(wú)參的構(gòu)造方法。

4.如果子類的構(gòu)造方法中既沒(méi)有顯示調(diào)用父類的構(gòu)造方法,而父類中又沒(méi)有無(wú)參的構(gòu)造方法,則編譯出錯(cuò)。

那你這里第一個(gè)super()無(wú)參的就是調(diào)用了上面Bird類的Bird()?方法!

super(name)這個(gè)有參數(shù)就是調(diào)用public?Bird(String?name){

this.name?=?name;?這個(gè)方法!super()?是調(diào)用父類的構(gòu)造函數(shù),你例子中有Bird()和Bird(String?name)兩個(gè)方法,super()是調(diào)用Bird()構(gòu)造函數(shù),而super(name)是調(diào)用Birth(String?name)構(gòu)造函數(shù)。注意super()?調(diào)用的是對(duì)應(yīng)參數(shù)個(gè)數(shù)和類型相同的父類構(gòu)造函數(shù)。?public?Chicken(String?name,String?crest)?{?super(name);?this.name?=?name;?}?應(yīng)該重復(fù)了吧,super(name)應(yīng)該就是this.name?=?name。

二、Java?語(yǔ)言中的?volatile?和synchronized有什么區(qū)別?

Java?語(yǔ)言中的?volatile?變量可以被看作是一種?“程度較輕的?synchronized”;與?synchronized?塊相比,volatile?變量所需的編碼較少,并且運(yùn)行時(shí)開(kāi)銷也較少,但是它所能實(shí)現(xiàn)的功能也僅是?synchronized?的一部分。

我們知道,在Java中設(shè)置變量值的操作,除了long和double類型的變量外都是原子操作,也就是說(shuō),對(duì)于變量值的簡(jiǎn)單讀寫操作沒(méi)有必要進(jìn)行同步。

這在JVM?1.2之前,Java的內(nèi)存模型實(shí)現(xiàn)總是從主存讀取變量,是不需要進(jìn)行特別的注意的。而隨著JVM的成熟和優(yōu)化,現(xiàn)在在多線程環(huán)境下volatile關(guān)鍵字的使用變得非常重要。

在當(dāng)前的Java內(nèi)存模型下,線程可以把變量保存在本地內(nèi)存(比如機(jī)器的寄存器)中,而不是直接在主存中進(jìn)行讀寫。這就可能造成一個(gè)線程在主存中修改了一個(gè)變量的值,而另外一個(gè)線程還繼續(xù)使用它在寄存器中的變量值的拷貝,造成數(shù)據(jù)的不一致。

要解決這個(gè)問(wèn)題,只需要像在本程序中的這樣,把該變量聲明為volatile(不穩(wěn)定的)即可,這就指示JVM,這個(gè)變量是不穩(wěn)定的,每次使用它都到主存中進(jìn)行讀取。一般說(shuō)來(lái),多任務(wù)環(huán)境下各任務(wù)間共享的標(biāo)志都應(yīng)該加volatile修飾。

Volatile修飾的成員變量在每次被線程訪問(wèn)時(shí),都強(qiáng)迫從共享內(nèi)存中重讀該成員變量的值。而且,當(dāng)成員變量發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫到共享內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。

Java語(yǔ)言規(guī)范中指出:為了獲得最佳速度,允許線程保存共享成員變量的私有拷貝,而且只當(dāng)線程進(jìn)入或者離開(kāi)同步代碼塊時(shí)才與共享成員變量的原始值對(duì)比。

這樣當(dāng)多個(gè)線程同時(shí)與某個(gè)對(duì)象交互時(shí),就必須要注意到要讓線程及時(shí)的得到共享成員變量的變化。

而volatile關(guān)鍵字就是提示VM:對(duì)于這個(gè)成員變量不能保存它的私有拷貝,而應(yīng)直接與共享成員變量交互。

使用建議:在兩個(gè)或者更多的線程訪問(wèn)的成員變量上使用volatile。當(dāng)要訪問(wèn)的變量已在synchronized代碼塊中,或者為常量時(shí),不必使用。

由于使用屏蔽掉了VM中必要的代碼優(yōu)化,所以在效率上比較低,因此一定在必要時(shí)才使用此關(guān)鍵字。

注意:聲明為volatile的簡(jiǎn)單變量如果當(dāng)前值由該變量以前的值相關(guān),那么volatile關(guān)鍵字不起作用,也就是說(shuō)如下的表達(dá)式都不是原子操作:

????n?=?n?+?1;?
????n++;?

如果要想使這種情況變成原子操作,需要使用synchronized關(guān)鍵字,如上的代碼可以改成如下的形式:

????public?static?synchronized?void?inc()?
????{?
????n++;?
????}?

將n=n+1改成了inc(),其中inc方法使用了synchronized關(guān)鍵字進(jìn)行方法同步。因此,在使用volatile關(guān)鍵字時(shí)要慎重,并不是只要簡(jiǎn)單類型變量使用volatile修飾,對(duì)這個(gè)變量的所有操作都是原來(lái)操作,當(dāng)變量的值由自身的上一個(gè)決定時(shí),如n=n+1、n++等,volatile關(guān)鍵字將失效,只有當(dāng)變量的值和自身上一個(gè)值無(wú)關(guān)時(shí)對(duì)該變量的操作才是原子級(jí)別的,如n?=?m?+?1,這個(gè)就是原級(jí)別的。所以在使用volatile關(guān)鍵時(shí)一定要謹(jǐn)慎,如果自己沒(méi)有把握,可以使用synchronized來(lái)代替volatile。

三、什么是互斥鎖?使用互斥鎖都有哪些注意事項(xiàng)?

1.男孩和女孩例子,每個(gè)女孩是一個(gè)對(duì)象,每個(gè)男孩是個(gè)線程。每個(gè)女孩都有自己的鎖池。每個(gè)男孩可能在鎖池里等待。

????Class?Girl{?
????Public?void?hand(){?
????}?
????Public?syncronized?void?kiss(){?
????}?
????}?
????Class?Boy?extends?Thread{?
????Public?void?run(){?
????}?
????}?

鎖標(biāo)記如果過(guò)多,就會(huì)出現(xiàn)線程等待其他線程釋放鎖標(biāo)記,而又都不釋放自己的鎖標(biāo)記供其他線程運(yùn)行的狀況。就是死鎖。

死鎖的兩種處理方法:統(tǒng)一排列鎖順序(解決不同方法中對(duì)多個(gè)共享資源的訪問(wèn))。

對(duì)象1的方法

synchronized(a)
synchronized(b)

對(duì)象2的方法

????synchronized(a)?
????synchronized(b)?

2.線程間通信(也就是線程間的相互協(xié)調(diào))

線程間通信使用的空間稱之為對(duì)象的等待池(wait?pool),該隊(duì)列也是屬于對(duì)象的空間的。

進(jìn)入等待池

使用Object類中wait()的方法,在運(yùn)行狀態(tài)中,線程調(diào)用wait(),此時(shí)表示線程將釋放自己所有的鎖標(biāo)記和CPU的占用,同時(shí)進(jìn)入這個(gè)對(duì)象的等待池。等待池的狀態(tài)也是阻塞狀態(tài),只不過(guò)線程釋放自己的鎖標(biāo)記。

退出等待池進(jìn)入鎖池

notify():將從對(duì)象的等待池中移走一個(gè)任意的線程,并放到鎖池中,那里的對(duì)象一直在等待,直到可以獲得對(duì)象的鎖標(biāo)記。

notifyAll():將從等待池中移走所有等待那個(gè)對(duì)象的線程并放到鎖池中,只有鎖池中的線程能獲取對(duì)象的鎖標(biāo)記,鎖標(biāo)記允許線程從上次因調(diào)用wait()而中斷的地方開(kāi)始繼續(xù)運(yùn)行。

注意:只能對(duì)加鎖的資源進(jìn)行wait()和notify()。

1)?wait():交出鎖和CPU的占用;

2)?notify():將從對(duì)象的等待池中移走一個(gè)任意的線程,并放到鎖池中,那里的對(duì)象一直在等待,直到可以獲得對(duì)象的鎖標(biāo)記。

3)?notifyAll():?將從等待池中移走所有等待那個(gè)對(duì)象的線程并放到鎖池中,只有鎖池中的線程能獲取對(duì)象的鎖標(biāo)記,鎖標(biāo)記允許線程從上次因調(diào)用wait()而中斷的地方開(kāi)始繼續(xù)運(yùn)行。

注:在java.io包中Vector?和?HashTable?之所以是線程安全的,是因?yàn)槊總€(gè)方法都有synchronized修飾。Static?方法可以加?synchronized?,?鎖的是類對(duì)象。

但是Vector?是?jdk?1.0?的?ArrayList?是?jdk1.2?所以實(shí)際應(yīng)用還是使用ArrayList

例子:

生產(chǎn)者和消費(fèi)者

一個(gè)柜臺(tái)一定數(shù)量的產(chǎn)品,柜臺(tái)滿時(shí)不能生產(chǎn),空時(shí)不能夠買。

四、Java中流的分類都有哪些?

1)從數(shù)據(jù)類型分為字節(jié)流和字符流

字節(jié)流類:

抽象父類:?InputStream,OutputStream

實(shí)現(xiàn)類包括如下幾種:

BufferedInputStream?緩沖流-過(guò)慮流
BufferedOutputStream
ByteArrayInputStream?字節(jié)數(shù)組流-節(jié)點(diǎn)流
ByteArrayOutputStream
DataInputStream?處理JAVA標(biāo)準(zhǔn)數(shù)據(jù)流-過(guò)慮流
DataOutputStream
FileInputStream?處理文件IO流-節(jié)點(diǎn)流
FileOutputStream
FilterInputStream?實(shí)現(xiàn)過(guò)慮流-字節(jié)過(guò)慮流父類
FilterOutputStream
PipedInputStream?管道流
PipedOutputStream
PrintStream?包含print()?和?println()
RandomAccessFile?支持隨機(jī)文件

抽象父類:Reader,?Writer

實(shí)現(xiàn)類:

BufferedReader
BufferedWriter
PrintWriter
CharArrayReader
CharArrayWriter
FileReader
FileWriter
FilterReader
FilterWriter
InputStreamReader
OutputStreamWriter
PipedReader
PipedWriter
StringReader
StringWriter

2)?從數(shù)據(jù)方向分為輸入流和輸出流

InputXXXXX?,?OutputXXXXX

3)?從流的功能分為節(jié)點(diǎn)流和過(guò)濾流

節(jié)點(diǎn)流用來(lái)傳輸數(shù)據(jù)。

過(guò)濾流用來(lái)封裝節(jié)點(diǎn)流或者其他過(guò)濾流,從而給節(jié)點(diǎn)流或其他的過(guò)濾流增加一個(gè)功能。

五、Java中父類和子類關(guān)系

父類的非私有化屬性(不同包的子類無(wú)法訪問(wèn)default修飾符)和方法可以默認(rèn)繼承到子類。

????Class?Son?extends?Father{?
????}?

而如果父類中的私有方法被子類調(diào)用的話,則編譯報(bào)錯(cuò)。

父類的構(gòu)造方法子類不可以繼承,更不存在覆蓋的問(wèn)題。

所以子類構(gòu)造方法默認(rèn)調(diào)用父類的無(wú)參構(gòu)造方法。(所以養(yǎng)成寫無(wú)參構(gòu)造的習(xí)慣)

如果子類訪問(wèn)父類的有參構(gòu)造方法,必須在子類構(gòu)造方法第一行使用super(參數(shù))

當(dāng)構(gòu)造一個(gè)對(duì)象的時(shí)候,系統(tǒng)先構(gòu)造父類對(duì)象,再構(gòu)造子類對(duì)象。

????Public?class?BMWcar?extends?Car{?
????Public?BMWcar(){?
????Super(int?alength);?//顯式的調(diào)用父類的構(gòu)造,默認(rèn)調(diào)用無(wú)參構(gòu)造?
????//所以父類沒(méi)有無(wú)參構(gòu)造的話,子類如果不加顯示調(diào)用其他構(gòu)造就會(huì)報(bào)錯(cuò)。這里的super是一個(gè)對(duì)父類的引用?
????}?
????}?
六、Java多線程常見(jiàn)面試題

1、定義線程

1)擴(kuò)展java.lang.Thread類。

此類中有個(gè)run()方法,應(yīng)該注意其用法:

public?void?run()如果該線程是使用獨(dú)立的?Runnable?運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該?Runnable?對(duì)象的?run?方法;否則,該方法不執(zhí)行任何操作并返回。

Thread?的子類應(yīng)該重寫該方法。

2)實(shí)現(xiàn)java.lang.Runnable接口。

void?run()

使用實(shí)現(xiàn)接口?Runnable?的對(duì)象創(chuàng)建一個(gè)線程時(shí),啟動(dòng)該線程將導(dǎo)致在獨(dú)立執(zhí)行的線程中調(diào)用對(duì)象的?run?方法。

方法?run?的常規(guī)協(xié)定是,它可能執(zhí)行任何所需的操作。

2、實(shí)例化線程

1)如果是擴(kuò)展java.lang.Thread類的線程,則直接new即可。

2)如果是實(shí)現(xiàn)了java.lang.Runnable接口的類,則用Thread的構(gòu)造方法:

Thread(Runnable?target)
Thread(Runnable?target,?String?name)
Thread(ThreadGroup?group,?Runnable?target)
Thread(ThreadGroup?group,?Runnable?target,?String?name)
Thread(ThreadGroup?group,?Runnable?target,?String?name,?long?stackSize)

3、啟動(dòng)線程

在線程的Thread對(duì)象上調(diào)用start()方法,而不是run()或者別的方法。

在調(diào)用start()方法之前:線程處于新?tīng)顟B(tài)中,新?tīng)顟B(tài)指有一個(gè)Thread對(duì)象,但還沒(méi)有一個(gè)真正的線程。

在調(diào)用start()方法之后:發(fā)生了一系列復(fù)雜的事情

啟動(dòng)新的執(zhí)行線程(具有新的調(diào)用棧);

該線程從新?tīng)顟B(tài)轉(zhuǎn)移到可運(yùn)行狀態(tài);

當(dāng)該線程獲得機(jī)會(huì)執(zhí)行時(shí),其目標(biāo)run()方法將運(yùn)行。

注意:對(duì)Java來(lái)說(shuō),run()方法沒(méi)有任何特別之處。像main()方法一樣,它只是新線程知道調(diào)用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調(diào)用run方法是合法的。但并不啟動(dòng)新的線程。

4、例子

1)實(shí)現(xiàn)Runnable接口的多線程例子。

????/**?
????*?實(shí)現(xiàn)Runnable接口的類?
????*?
????*?@author?leizhimin?2008-9-13?18:12:10?
????*/?
????public?class?DoSomething?implements?Runnable?{?
????private?String?name;?
?????
????public?DoSomething(String?name)?{?
????this.name?=?name;?
????}?
?????
????public?void?run()?{?
????for?(int?i?=?0;?i?<?5;?i++)?{?
????for?(long?k?=?0;?k?<?100000000;?k++)?;?
????System.out.println(name?+?“:?”?+?i);?
????}?
????}?
????}?
?????
????/**?
????*?測(cè)試Runnable類實(shí)現(xiàn)的多線程程序?
????*?
????*?@author?leizhimin?2008-9-13?18:15:02?
????*/?
????public?class?TestRunnable?{?
????public?static?void?main(String[]?args)?{?
????DoSomething?ds1?=?new?DoSomething(“阿三”);?
????DoSomething?ds2?=?new?DoSomething(“李四”);?
?????
????Thread?t1?=?new?Thread(ds1);?
????Thread?t2?=?new?Thread(ds2);?
?????
????t1.start();?
????t2.start();?
????}?
????}?

執(zhí)行結(jié)果:

李四:?0
阿三:?0
李四:?1
阿三:?1
李四:?2
李四:?3
阿三:?2
李四:?4
阿三:?3
阿三:?4
Process?finished?with?exit?code?0

2)擴(kuò)展Thread類實(shí)現(xiàn)的多線程例子。

????/**?
????*?測(cè)試擴(kuò)展Thread類實(shí)現(xiàn)的多線程程序?
????*?
????*?@author?leizhimin?2008-9-13?18:22:13?
????*/?
????public?class?TestThread?extends?Thread{?
????public?TestThread(String?name)?{?
????super(name);?
????}?
?????
????public?void?run()?{?
????for(int?i?=?0;i<5;i++){?
????for(long?k=?0;?k?<100000000;k++);?
????System.out.println(this.getName()+”?:”+i);?
????}?
????}?
?????
????public?static?void?main(String[]?args)?{?
????Thread?t1?=?new?TestThread(“阿三”);?
????Thread?t2?=?new?TestThread(“李四”);?
????t1.start();?
????t2.start();?
????}?
????}?

執(zhí)行結(jié)果:

阿三?:0
李四?:0
阿三?:1
李四?:1
阿三?:2
李四?:2
阿三?:3
阿三?:4
李四?:3
李四?:4
Process?finished?with?exit?code?0

對(duì)于上面的多線程程序代碼來(lái)說(shuō),輸出的結(jié)果是不確定的。其中的一條語(yǔ)句for(long?k=?0;?k?<100000000;k++);是用來(lái)模擬一個(gè)非常耗時(shí)的操作的。

5、一些常見(jiàn)問(wèn)題

1)線程的名字,一個(gè)運(yùn)行中的線程總是有名字的,名字有兩個(gè)來(lái)源,一個(gè)是虛擬機(jī)自己給的名字,一個(gè)是你自己的定的名字。在沒(méi)有指定線程名字的情況下,虛擬機(jī)總會(huì)為線程指定名字,并且主線程的名字總是mian,非主線程的名字不確定。

2)線程都可以設(shè)置名字,也可以獲取線程的名字,連主線程也不例外。

3)獲取當(dāng)前線程的對(duì)象的方法是:Thread.currentThread();

4)在上面的代碼中,只能保證:每個(gè)線程都將啟動(dòng),每個(gè)線程都將運(yùn)行直到完成。一系列線程以某種順序啟動(dòng)并不意味著將按該順序執(zhí)行。對(duì)于任何一組啟動(dòng)的線程來(lái)說(shuō),調(diào)度程序不能保證其執(zhí)行次序,持續(xù)時(shí)間也無(wú)法保證。

5)當(dāng)線程目標(biāo)run()方法結(jié)束時(shí)該線程完成。

6)一旦線程啟動(dòng),它就永遠(yuǎn)不能再重新啟動(dòng)。只有一個(gè)新的線程可以被啟動(dòng),并且只能一次。一個(gè)可運(yùn)行的線程或死線程可以被重新啟動(dòng)。

7)線程的調(diào)度是JVM的一部分,在一個(gè)CPU的機(jī)器上上,實(shí)際上一次只能運(yùn)行一個(gè)線程。一次只有一個(gè)線程棧執(zhí)行。JVM線程調(diào)度程序決定實(shí)際運(yùn)行哪個(gè)處于可運(yùn)行狀態(tài)的線程。眾多可運(yùn)行線程中的某一個(gè)會(huì)被選中做為當(dāng)前線程??蛇\(yùn)行線程被選擇運(yùn)行的順序是沒(méi)有保障的。

8)盡管通常采用隊(duì)列形式,但這是沒(méi)有保障的。隊(duì)列形式是指當(dāng)一個(gè)線程完成“一輪”時(shí),它移到可運(yùn)行隊(duì)列的尾部等待,直到它最終排隊(duì)到該隊(duì)列的前端為止,它才能被再次選中。事實(shí)上,我們把它稱為可運(yùn)行池而不是一個(gè)可運(yùn)行隊(duì)列,目的是幫助認(rèn)識(shí)線程并不都是以某種有保障的順序排列唱呢個(gè)一個(gè)隊(duì)列的事實(shí)。

9)盡管我們沒(méi)有無(wú)法控制線程調(diào)度程序,但可以通過(guò)別的方式來(lái)影響線程調(diào)度的方式。

七、java經(jīng)典面試題

總結(jié)了一下java的一些企業(yè)常面試的面試題,也可以說(shuō)是堪稱經(jīng)典吧!大部分企業(yè)的面試題,差不多都會(huì)以下我列出的面試題!而且面試題為紅色的題更是企業(yè)經(jīng)常面試的,可以說(shuō)是屢試不爽,大家如果看到了我的這篇文章,那么請(qǐng)你進(jìn)來(lái)看看,會(huì)對(duì)你有不小的收獲的。

Java基礎(chǔ)方面:

1、Static?Nested?Class?和?Inner?Class的不同。

Static?Nested?Class是被聲明為靜態(tài)(static)的內(nèi)部類,它可以不依賴于外部類實(shí)例被實(shí)例化。而通常的內(nèi)部類需要在外部類實(shí)例化后才能實(shí)例化。

2、java.lang.String類是否能被繼承和修改,為什么?

java.lang.String類是final類型的,因此不可以繼承這個(gè)類、不能修改這個(gè)類。為了提高效率節(jié)省空間,我們應(yīng)該用StringBuffer類

3、int?和?Integer?有什么區(qū)別?

Java?提供兩種不同的類型:引用類型和原始類型(或內(nèi)置類型)。Int是java的原始數(shù)據(jù)類型,Integer是java為int提供的封裝類。Java為每個(gè)原始類型提供了封裝類。

原始類型封裝類

booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

引?用類型和原始類型的行為完全不同,并且它們具有不同的語(yǔ)義。引用類型和原始類型具有不同的特征和用法,它們包括:大小和速度問(wèn)題,這種類型以哪種類型的數(shù)?據(jù)結(jié)構(gòu)存儲(chǔ),當(dāng)引用類型和原始類型用作某個(gè)類的實(shí)例數(shù)據(jù)時(shí)所指定的缺省值。對(duì)象引用實(shí)例變量的缺省值為?null,而原始類型實(shí)例變量的缺省值與它們的類型有關(guān)。

4、String?和StringBuffer的區(qū)別。

JAVA?平臺(tái)提供了兩個(gè)類:String和StringBuffer,它們可以儲(chǔ)存和操作字符串,即包含多個(gè)字符的字符數(shù)據(jù)。這個(gè)String類提供了數(shù)值不可改?變的字符串。而這個(gè)StringBuffer類提供的字符串進(jìn)行修改。當(dāng)你知道字符數(shù)據(jù)要改變的時(shí)候你就可以使用StringBuffer。典型地,你可?以使用StringBuffers來(lái)動(dòng)態(tài)構(gòu)造字符數(shù)據(jù)。

5、運(yùn)行時(shí)異常與一般異常有何異同?

異常表示程序運(yùn)行過(guò)程中可能出現(xiàn)的非正常狀態(tài),運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見(jiàn)運(yùn)行錯(cuò)誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運(yùn)行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常。

6、說(shuō)出Servlet的生命周期,并說(shuō)出Servlet和CGI的區(qū)別。

Servlet被服務(wù)器實(shí)例化后,容器運(yùn)行其init方法,請(qǐng)求到達(dá)時(shí)運(yùn)行其service方法,service方法自動(dòng)派遣運(yùn)行與請(qǐng)求對(duì)應(yīng)的doXXX方法(doGet,doPost)等,當(dāng)服務(wù)器決定將實(shí)例銷毀的時(shí)候調(diào)用其destroy方法。

與cgi的區(qū)別在于servlet處于服務(wù)器進(jìn)程中,它通過(guò)多線程方式運(yùn)行其service方法,一個(gè)實(shí)例可以服務(wù)于多個(gè)請(qǐng)求,并且其實(shí)例一般不會(huì)銷毀,而CGI對(duì)每個(gè)請(qǐng)求都產(chǎn)生新的進(jìn)程,服務(wù)完成后就銷毀,所以效率上低于servlet。

7、說(shuō)出ArrayList,Vector,?LinkedList的存儲(chǔ)性能和特性。

ArrayList?和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素,但是插入元素要涉及數(shù)組元?素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,?而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。

8、EJB是基于哪些技術(shù)實(shí)現(xiàn)的?并說(shuō)出SessionBean和EntityBean的區(qū)別,StatefulBean和StatelessBean的區(qū)別。

EJB包括Session?Bean、Entity?Bean、Message?Driven?Bean,基于JNDI、RMI、JAT等技術(shù)實(shí)現(xiàn)。

SessionBean在J2EE應(yīng)用程序中被用來(lái)完成一些服務(wù)器端的業(yè)務(wù)操作,例如訪問(wèn)數(shù)據(jù)庫(kù)、調(diào)用其他EJB組件。EntityBean被用來(lái)代表應(yīng)用系統(tǒng)中用到的數(shù)據(jù)。

對(duì)于客戶機(jī),SessionBean是一種非持久性對(duì)象,它實(shí)現(xiàn)某些在服務(wù)器上運(yùn)行的業(yè)務(wù)邏輯。

對(duì)于客戶機(jī),EntityBean是一種持久性對(duì)象,它代表一個(gè)存儲(chǔ)在持久性存儲(chǔ)器中的實(shí)體的對(duì)象視圖,或是一個(gè)由現(xiàn)有企業(yè)應(yīng)用程序?qū)崿F(xiàn)的實(shí)體。

Session?Bean?還可以再細(xì)分為?Stateful?Session?Bean?與?Stateless?Session?Bean?,這兩種的?Session?Bean都可以將系統(tǒng)邏輯放在?method之中執(zhí)行,不同的是?Stateful?Session?Bean?可以記錄呼叫者的狀態(tài),因此通常來(lái)說(shuō),一個(gè)使用者會(huì)有一個(gè)相對(duì)應(yīng)的?Stateful?Session?Bean?的實(shí)體。Stateless?Session?Bean?雖然也是邏輯組件,但是他卻不負(fù)責(zé)記錄使用者狀態(tài),也就是說(shuō)當(dāng)使用者呼叫?Stateless?Session?Bean?的時(shí)候,EJB?Container?并不會(huì)找尋特定的?Stateless?Session?Bean?的實(shí)體來(lái)執(zhí)行這個(gè)?method。換言之,很可能數(shù)個(gè)使用者在執(zhí)行某個(gè)?Stateless?Session?Bean?的?methods?時(shí),會(huì)是同一個(gè)?Bean?的?Instance?在執(zhí)行。從內(nèi)存方面來(lái)看,?Stateful?Session?Bean?與?Stateless?Session?Bean?比較,?Stateful?Session?Bean?會(huì)消耗?J2EE?Server?較多的內(nèi)存,然而?Stateful?Session?Bean?的優(yōu)勢(shì)卻在于他可以維持使用者的狀態(tài)。

9、Collection?和?Collections的區(qū)別。

Collection是集合類的上級(jí)接口,繼承與他的接口主要有Set?和List.

Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。

10、&和&&的區(qū)別。

&是位運(yùn)算符,表示按位與運(yùn)算,&&是邏輯運(yùn)算符,表示邏輯與(and)。

11、HashMap和Hashtable的區(qū)別。

HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable。

HashMap允許將null作為一個(gè)entry的key或者value,而Hashtable不允許。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。

Hashtable繼承自Dictionary類,而HashMap是Java1.2引進(jìn)的Map?interface的一個(gè)實(shí)現(xiàn)。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個(gè)線程訪問(wèn)Hashtable時(shí),不需要自己為它的方法實(shí)現(xiàn)同步,而HashMap?就必須為之提供外同步。

Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會(huì)有很大的差異。

12、final,?finally,?finalize的區(qū)別。

final?用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。

finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。

13、sleep()?和?wait()?有什么區(qū)別?

sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。

wait是Object類的方法,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。

14、Overload和Override的區(qū)別。Overloaded的方法是否可以改變返回值的類型?

方?法的重寫Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。重寫Overriding是父類與子類之間多態(tài)性的一種表現(xiàn),重?載Overloading是一個(gè)類中多態(tài)性的一種表現(xiàn)。如果在子類中定義某方法與其父類有相同的名稱和參數(shù),我們說(shuō)該方法被重寫?(Overriding)。子類的對(duì)象使用這個(gè)方法時(shí),將調(diào)用子類中的定義,對(duì)它而言,父類中的定義如同被”屏蔽”了。如果在一個(gè)類中定義了多個(gè)同名的方?法,它們或有不同的參數(shù)個(gè)數(shù)或有不同的參數(shù)類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類型。

15、error和exception有什么區(qū)別?

error?表示恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問(wèn)題。比如說(shuō)內(nèi)存溢出。不可能指望程序能處理這樣的情況。

exception?表示一種設(shè)計(jì)或?qū)崿F(xiàn)問(wèn)題。也就是說(shuō),它表示如果程序運(yùn)行正常,從不會(huì)發(fā)生的情況。

16、同步和異步有何異同,在什么情況下分別使用他們?舉例說(shuō)明。

如果數(shù)據(jù)將在線程間共享。例如正在寫的數(shù)據(jù)以后可能被另一個(gè)線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫過(guò)了,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進(jìn)行同步存取。

當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長(zhǎng)時(shí)間來(lái)執(zhí)行的方法,并且不希望讓程序等待方法的返回時(shí),就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率。

17、abstract?class和interface有什么區(qū)別?

聲?明方法的存在而不去實(shí)現(xiàn)它的類被叫做抽象類(abstract?class),它用于要?jiǎng)?chuàng)建一個(gè)體現(xiàn)某些基本行為的類,并為該類聲明方法,但不能在該類中實(shí)現(xiàn)該類的情況。不能創(chuàng)建abstract?類的實(shí)例。然而可以創(chuàng)建一個(gè)變量,其類型是一個(gè)抽象類,并讓它指向具體子類的一個(gè)實(shí)例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。Abstract?類的子類為它們父類中的所有抽象方法提供實(shí)現(xiàn),否則它們也是抽象類為。取而代之,在子類中實(shí)現(xiàn)該方法。知道其行為的其它類可以在類中實(shí)現(xiàn)這些方法。

接?口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過(guò)實(shí)現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒(méi)有一個(gè)有?程序體。接口只可以定義static?final成員變量。接口的實(shí)現(xiàn)與子類相似,除了該實(shí)現(xiàn)類不能從接口定義中繼承行為。當(dāng)類實(shí)現(xiàn)特殊接口時(shí),它定義(即將程序體給予)所有這種接口的方法。?然后,它可以在實(shí)現(xiàn)了該接口的類的任何對(duì)象上調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到?接口類型或從接口類型轉(zhuǎn)換,instanceof?運(yùn)算符可以用來(lái)決定某對(duì)象的類是否實(shí)現(xiàn)了接口。

18、heap和stack有什么區(qū)別。

棧是一種線形集合,其添加和刪除元素的操作應(yīng)在同一段完成。棧按照后進(jìn)先出的方式進(jìn)行處理。

堆是棧的一個(gè)組成元素

19、forward?和redirect的區(qū)別

forward是服務(wù)器請(qǐng)求資源,服務(wù)器直接訪問(wèn)目標(biāo)地址的URL,把那個(gè)URL的響應(yīng)內(nèi)容讀取過(guò)來(lái),然后把這些內(nèi)容再發(fā)給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來(lái)的,所以它的地址欄中還是原來(lái)的地址。
redirect就是服務(wù)端根據(jù)邏輯,發(fā)送一個(gè)狀態(tài)碼,告訴瀏覽器重新去請(qǐng)求那個(gè)地址,一般來(lái)說(shuō)瀏覽器會(huì)用剛才請(qǐng)求的所有參數(shù)重新請(qǐng)求,所以session,request參數(shù)都可以獲取。

20、EJB與JAVA?BEAN的區(qū)別?
Java?Bean?是可復(fù)用的組件,對(duì)Java?Bean并沒(méi)有嚴(yán)格的規(guī)范,理論上講,任何一個(gè)Java類都可以是一個(gè)Bean。但通常情況下,由于Java?Bean是被容器所創(chuàng)建(如Tomcat)的,所以Java?Bean應(yīng)具有一個(gè)無(wú)參的構(gòu)造器,另外,通常Java?Bean還要實(shí)現(xiàn)Serializable接口用于實(shí)現(xiàn)Bean的持久性。Java?Bean實(shí)際上相當(dāng)于微軟COM模型中的本地進(jìn)程內(nèi)COM組件,它是不能被跨進(jìn)程訪問(wèn)的。Enterprise?Java?Bean?相當(dāng)于DCOM,即分布式組件。它是基于Java的遠(yuǎn)程方法調(diào)用(RMI)技術(shù)的,所以EJB可以被遠(yuǎn)程訪問(wèn)(跨進(jìn)程、跨計(jì)算機(jī))。但EJB必須被布署在?諸如Webspere、WebLogic這樣的容器中,EJB客戶從不直接訪問(wèn)真正的EJB組件,而是通過(guò)其容器訪問(wèn)。EJB容器是EJB組件的代理,?EJB組件由容器所創(chuàng)建和管理??蛻敉ㄟ^(guò)容器來(lái)訪問(wèn)真正的EJB組件。
八、戴爾公司電話面試Java

接到了dell公司項(xiàng)目經(jīng)理的電話面試,我們從java?的接口,abstract函數(shù),談的c++的虛函數(shù),然后談到j(luò)ava?native?interface。談到動(dòng)態(tài)庫(kù),談到靜態(tài)庫(kù),然后談到了進(jìn)程間通訊,操作系統(tǒng)是如何管理進(jìn)程的,已經(jīng)操作系統(tǒng)原理。談到了android的framework的部分原理,談到了aidl接口。

九、一朋友面試失敗后得到的一個(gè)回復(fù)信?你被涮后有過(guò)回復(fù)信嗎?

尊敬的應(yīng)聘者xxx,

非常感謝您到敝公司來(lái)面試。經(jīng)過(guò)我們對(duì)您的表現(xiàn)的認(rèn)真評(píng)估,認(rèn)為您目前還不適合敝公司的職位。如果您想在Java開(kāi)發(fā)方面有好的發(fā)展,我們對(duì)您有以下建議:

1.?要注重基礎(chǔ)知識(shí)的學(xué)習(xí),不要只會(huì)SSH框架。

2.?多學(xué)習(xí)一些Linux方面的知識(shí)。

3.?推薦您看看Java核心技術(shù),Think?in?java這兩本書。

4.?建議您閑時(shí)上一些技術(shù)論壇看看,同大家多交流交流技術(shù)。

十、什么是觀察者模式(Observer)?

觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,讓他們能夠自動(dòng)更新自己

觀察者模式的組成

抽象主題角色:把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)集合中,每個(gè)抽象主題角色都可以有任意數(shù)量的觀察者。抽象主題提供一個(gè)接口,可以增加和刪除觀察者角色。一般用一個(gè)抽象類或接口來(lái)實(shí)現(xiàn)。

抽象觀察者角色:為所有具體的觀察者定義一個(gè)接口,在得到主題的通知時(shí)更新自己。

從AWT1.1開(kāi)始圖形系統(tǒng)的事件模型采用觀察者模式,因此觀察者模式在Java語(yǔ)言中的地位極其重要。

在xml解析中的SAX也采用了觀察者模式來(lái)實(shí)現(xiàn)。

Java也提供了對(duì)觀察者模式的內(nèi)置支持。

Observable類用于創(chuàng)建可以觀測(cè)到你的程序中其他部分的子類。當(dāng)這種子類的對(duì)象發(fā)生變化時(shí),觀測(cè)類被通知。觀測(cè)類必須實(shí)現(xiàn)定義了update(?)方法的Observer接口。當(dāng)一個(gè)觀測(cè)程序被通知到一個(gè)被觀測(cè)對(duì)象的改變時(shí),update(?)方法被調(diào)用。

一個(gè)被觀測(cè)的對(duì)象必須服從下面的兩個(gè)簡(jiǎn)單規(guī)則。第一,如果它被改變了,它必須調(diào)用setChanged(?)方法。第二,當(dāng)它準(zhǔn)備通知觀測(cè)程序它的改變時(shí),它必須調(diào)用notifyObservers(?)方法。這導(dǎo)致了在觀測(cè)對(duì)象中對(duì)update(?)方法的調(diào)用。注意——當(dāng)對(duì)象在調(diào)用notifyObservers(?)方法之前,沒(méi)有調(diào)用setChanged(?)方法,就不會(huì)有什么動(dòng)作發(fā)生。在update(?)被調(diào)用之前,被觀測(cè)對(duì)象必須調(diào)用setChanged(?)和notifyObservers(?)兩種方法。

注意notifyObservers()有兩種形式:一種帶有參數(shù)而另一種沒(méi)有。當(dāng)用參數(shù)調(diào)用notifyObservers(?)方法時(shí),該對(duì)象被傳給觀測(cè)程序的update(?)方法作為其第二個(gè)參數(shù)。否則,將給update(?)方法傳遞一個(gè)null??梢允褂玫诙€(gè)參數(shù)傳遞適合于你的應(yīng)用程序的任何類型的對(duì)象。

為了觀測(cè)一個(gè)可觀測(cè)的對(duì)象,必須實(shí)現(xiàn)Observer接口。這個(gè)接口僅僅定義了如下所示的一個(gè)方法。

????void?update(Observable?observOb,?Object?arg)?

這里,observOb是被觀測(cè)的對(duì)象,而arg是由notifyObservers(?)方法傳遞的值。當(dāng)被觀測(cè)對(duì)象發(fā)生了改變,調(diào)用update(?)方法。

十一、JavaEE?N層架構(gòu)的好處都有哪些?

JavaEE帶來(lái)的好處是雙向的,對(duì)于開(kāi)發(fā)應(yīng)用的公司和使用它的客戶,優(yōu)點(diǎn)主要在于4個(gè)方面。

1、簡(jiǎn)化了體系和開(kāi)發(fā)。相對(duì)于傳統(tǒng)的應(yīng)用開(kāi)發(fā),JavaEE提供了簡(jiǎn)單的、基于組件的開(kāi)發(fā)模型。這個(gè)模型提供了WORA(Write?Once,?Run?Anywhere)的可移植性,只要符合JavaEE規(guī)范的服務(wù)器,就可以運(yùn)行應(yīng)用。同時(shí),基于組件的開(kāi)發(fā)模型也大大提高了生產(chǎn)力。

2、集成現(xiàn)有的企業(yè)信息系統(tǒng)。JavaEE平臺(tái),與JavaSE平臺(tái)一樣,提供訪問(wèn)現(xiàn)有的企業(yè)信息系統(tǒng)的一些工業(yè)標(biāo)準(zhǔn)API;

3、提供可擴(kuò)展性。當(dāng)前JavaEE容器向組件提供事務(wù)支持、數(shù)據(jù)庫(kù)連接、生命周期管理和影響性能的其它特性,從而提供可擴(kuò)展性(scalability)。

4、安全機(jī)制。JavaEE支持豐富的跨越整個(gè)體系的一致的安全措施。

十二、四種操作xml的方式:SAX,?DOM,?JDOM?,?DOM4J的比較

1、DOM(JAXP?Crimson解析器)

DOM是用與平臺(tái)和語(yǔ)言無(wú)關(guān)的方式表示XML文檔的官方W3C標(biāo)準(zhǔn)。DOM是以層次結(jié)構(gòu)組織的節(jié)點(diǎn)或信息片斷的集合。

這個(gè)層次結(jié)構(gòu)允許開(kāi)發(fā)人員在樹(shù)中尋找特定信息。分析該結(jié)構(gòu)通常需要加載整個(gè)文檔和構(gòu)造層次結(jié)構(gòu),然后才能做任何工作。

由于它是基于信息層次的,因而DOM被認(rèn)為是基于樹(shù)或基于對(duì)象的。DOM以及廣義的基于樹(shù)的處理具有幾個(gè)優(yōu)點(diǎn)。

首先,由于樹(shù)在內(nèi)存中是持久的,因此可以修改它以便應(yīng)用程序能對(duì)數(shù)據(jù)和結(jié)構(gòu)作出更改。

它還可以在任何時(shí)候在樹(shù)中上下導(dǎo)航,而不是像SAX那樣是一次性的處理。DOM使用起來(lái)也要簡(jiǎn)單得多。

2、SAX

SAX處理的優(yōu)點(diǎn)非常類似于流媒體的優(yōu)點(diǎn)。分析能夠立即開(kāi)始,而不是等待所有的數(shù)據(jù)被處理。而且,由于應(yīng)用程序只是在讀取數(shù)據(jù)時(shí)檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲(chǔ)在內(nèi)存中。這對(duì)于大型文檔來(lái)說(shuō)是個(gè)巨大的優(yōu)點(diǎn)。事實(shí)上,應(yīng)用程序甚至不必解析整個(gè)文檔;它可以在某個(gè)條件得到滿足時(shí)停止解析。一般來(lái)說(shuō),SAX還比它的替代者DOM快許多。?選擇DOM還是選擇SAX??對(duì)于需要自己編寫代碼來(lái)處理XML文檔的開(kāi)發(fā)人員來(lái)說(shuō),選擇DOM還是SAX解析模型是一個(gè)非常重要的設(shè)計(jì)決策。?DOM采用建立樹(shù)形結(jié)構(gòu)的方式訪問(wèn)XML文檔,而SAX采用的事件模型。

DOM解析器把XML文檔轉(zhuǎn)化為一個(gè)包含其內(nèi)容的樹(shù),并可以對(duì)樹(shù)進(jìn)行遍歷。用DOM解析模型的優(yōu)點(diǎn)是編程容易,開(kāi)發(fā)人員只需要調(diào)用建樹(shù)的指令,然后利用navigation?APIs訪問(wèn)所需的樹(shù)節(jié)點(diǎn)來(lái)完成任務(wù)??梢院苋菀椎奶砑雍托薷臉?shù)中的元素。然而由于使用DOM解析器的時(shí)候需要處理整個(gè)XML文檔,所以對(duì)性能和內(nèi)存的要求比較高,尤其是遇到很大的XML文件的時(shí)候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務(wù)中。

SAX解析器采用了基于事件的模型,它在解析XML文檔的時(shí)候可以觸發(fā)一系列的事件,當(dāng)發(fā)現(xiàn)給定的tag的時(shí)候,它可以激活一個(gè)回調(diào)方法,
告訴該方法制定的標(biāo)簽已經(jīng)找到。SAX對(duì)內(nèi)存的要求通常會(huì)比較低,因?yàn)樗岄_(kāi)發(fā)人員自己來(lái)決定所要處理的tag。
特別是當(dāng)開(kāi)發(fā)人員只需要處理文檔中所包含的部分?jǐn)?shù)據(jù)時(shí),SAX這種擴(kuò)展能力得到了更好的體現(xiàn)。但用SAX解析器的時(shí)候編碼工作會(huì)比較困難,
而且很難同時(shí)訪問(wèn)同一個(gè)文檔中的多處不同數(shù)據(jù)。

3、JDOM

JDOM的目的是成為Java特定文檔模型,它簡(jiǎn)化與XML的交互并且比使用DOM實(shí)現(xiàn)更快。由于是第一個(gè)Java特定模型,JDOM一直得到大力推廣和促進(jìn)。

正在考慮通過(guò)“Java規(guī)范請(qǐng)求JSR-102”將它最終用作“Java標(biāo)準(zhǔn)擴(kuò)展”。從2000年初就已經(jīng)開(kāi)始了JDOM開(kāi)發(fā)。

JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡(jiǎn)化了API,但是也限制了靈活性。

第二,API大量使用了Collections類,簡(jiǎn)化了那些已經(jīng)熟悉這些類的Java開(kāi)發(fā)者的使用。

JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問(wèn)題”(根據(jù)學(xué)習(xí)曲線假定為20%)。JDOM對(duì)于大多數(shù)Java/XML應(yīng)用程序來(lái)說(shuō)當(dāng)然是有用的,并且大多數(shù)開(kāi)發(fā)者發(fā)現(xiàn)API比DOM容易理解得多。JDOM還包括對(duì)程序行為的相當(dāng)廣泛檢查以防止用戶做任何在XML中無(wú)意義的事。

然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯(cuò)誤)。這也許是比學(xué)習(xí)DOM或JDOM接口都更有意義的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器來(lái)解析和驗(yàn)證輸入XML文檔(盡管它還可以將以前構(gòu)造的DOM表示作為輸入)。

它包含一些轉(zhuǎn)換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發(fā)布的開(kāi)放源碼。

4、DOM4J

雖然DOM4J代表了完全獨(dú)立的開(kāi)發(fā)結(jié)果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML?Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項(xiàng),它通過(guò)DOM4J?API和標(biāo)準(zhǔn)DOM接口具有并行訪問(wèn)功能。從2000下半年開(kāi)始,它就一直處于開(kāi)發(fā)之中。

為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復(fù)雜的API的代價(jià),但是它提供了比JDOM大得多的靈活性。在添加靈活性、XPath集成和對(duì)大文檔處理的目標(biāo)時(shí),DOM4J的目標(biāo)與JDOM是一樣的:針對(duì)Java開(kāi)發(fā)者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實(shí)現(xiàn)在本質(zhì)上處理所有Java/XML問(wèn)題的目標(biāo)。在完成該目標(biāo)時(shí),它比JDOM更少?gòu)?qiáng)調(diào)防止不正確的應(yīng)用程序行為。

DOM4J是一個(gè)非常非常優(yōu)秀的Java?XML?API,具有性能優(yōu)異、功能強(qiáng)大和極端易用使用的特點(diǎn),同時(shí)它也是一個(gè)開(kāi)放源代碼的軟件。如今你可以看到越來(lái)越多的Java軟件都在使用DOM4J來(lái)讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J。

比較

1、DOM4J性能最好,連Sun的JAXM也在用DOM4J。目前許多開(kāi)源項(xiàng)目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來(lái)讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J。

2、JDOM和DOM在性能測(cè)試時(shí)表現(xiàn)不佳,在測(cè)試10M文檔時(shí)內(nèi)存溢出。在小文檔情況下還值得考慮使用DOM和JDOM。雖然JDOM的開(kāi)發(fā)者已經(jīng)說(shuō)明他們期望在正式發(fā)行版前專注性能問(wèn)題,但是從性能觀點(diǎn)來(lái)看,它確實(shí)沒(méi)有值得推薦之處。另外,DOM仍是一個(gè)非常好的選擇。DOM實(shí)現(xiàn)廣泛應(yīng)用于多種編程語(yǔ)言。它還是許多其它與XML相關(guān)的標(biāo)準(zhǔn)的基礎(chǔ),因?yàn)樗将@得W3C推薦(與基于非標(biāo)準(zhǔn)的Java模型相對(duì)),所以在某些類型的項(xiàng)目中可能也需要它(如在JavaScript中使用DOM)。

3、SAX表現(xiàn)較好,這要依賴于它特定的解析方式-事件驅(qū)動(dòng)。一個(gè)SAX檢測(cè)即將到來(lái)的XML流,但并沒(méi)有載入到內(nèi)存(當(dāng)然當(dāng)XML流被讀入時(shí),會(huì)有部分文檔暫時(shí)隱藏在內(nèi)存中)



本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉