自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

new的奧秘:Java中new關(guān)鍵字與類(lèi)加載器

原創(chuàng)
開(kāi)發(fā) 后端
"new"可以說(shuō)是Java開(kāi)發(fā)者最常用的關(guān)鍵字,我們使用new創(chuàng)建對(duì)象,使用new并通過(guò)類(lèi)加載器來(lái)實(shí)例化任何我們需要的東西,但你是否深入了解過(guò)new在編譯的瞬間都做了什么?

【51CTO獨(dú)家特稿】在Java中使用new關(guān)鍵字創(chuàng)建對(duì)象變得很容易了,事實(shí)上,對(duì)這些事情你是不需要考慮的。需要訪(fǎng)問(wèn)一個(gè)文件嗎?只需要?jiǎng)?chuàng)建一個(gè)新的File實(shí)例:new File(“build.properties”),對(duì)于大多數(shù)Java開(kāi)發(fā)人員而言,這就是他們需要知道的一切,是不是很簡(jiǎn)單呢?!但當(dāng)你使用了多個(gè)類(lèi)加載器時(shí),問(wèn)題就不一樣了。

這是我一年多來(lái)的第一反應(yīng),我就是不想知道這些東西,但奇怪的是,類(lèi)加載器其實(shí)非常簡(jiǎn)單,大多數(shù)Java開(kāi)發(fā)人員都知道編譯時(shí)通過(guò)Java文件生成.class類(lèi)文件,然后由Java虛擬機(jī)(JVM)載入這些編譯后的類(lèi),這就是類(lèi)加載器最基本的功能,但是和線(xiàn)程一樣,問(wèn)題不是理解他們做什么,而是讓它們一起工作。

你聽(tīng)到過(guò)多少次“這是類(lèi)加載器的問(wèn)題”?我承認(rèn)我聽(tīng)到過(guò)很多次,我自己也說(shuō)過(guò)很多次。只要你的應(yīng)用程序中不止一個(gè)類(lèi)加載器,你不得不擔(dān)心哪些類(lèi)可以相互看到對(duì)方,這很容易成為一場(chǎng)噩夢(mèng)。有關(guān)類(lèi)加載器行為我將另外用一篇文章來(lái)說(shuō),現(xiàn)在我們還是回到new關(guān)鍵字吧。

當(dāng)你創(chuàng)建一個(gè)新對(duì)象時(shí),JVM首先加載類(lèi),當(dāng)你使用new時(shí)這是透明的,問(wèn)題是使用什么類(lèi)加載器?以及為什么要使用它?
設(shè)想一個(gè)Grails情景,我們有一套基于Gant的構(gòu)建系統(tǒng),載入構(gòu)建腳本并執(zhí)行它們,我們以實(shí)例化一個(gè)Jetty服務(wù)器并啟動(dòng)它作為示例,對(duì)象的創(chuàng)建順序是這樣的:

Java中對(duì)象創(chuàng)建的順序 
對(duì)象的創(chuàng)建順序

事實(shí)上,上圖展示的僅僅是一個(gè)簡(jiǎn)化的真實(shí)情況。

前3個(gè)類(lèi)都在我們將要調(diào)用的生成類(lèi)加載器的類(lèi)路徑下,因此是一次性將生成時(shí)需要用到的所有類(lèi)全部加載了,但Jetty的Server類(lèi)怎么加載呢?最重要的是要知道Server類(lèi)必須要通過(guò)加載Grails Web應(yīng)用程序相同的類(lèi)加載器加載,雖然你可以將你自己的類(lèi)加載器嵌入到服務(wù)器中,如果與加載Server的不一樣,將會(huì)出現(xiàn)可怕的類(lèi)加載器問(wèn)題。

考慮到這一點(diǎn),讓我們看看如果RunApp腳本使用new創(chuàng)建服務(wù)器實(shí)例會(huì)發(fā)生什么:

  1. def server = new org.mortbay.jetty.Server()  
  2. ...  
  3. server.start() 

現(xiàn)在你應(yīng)該問(wèn)你自己“加載Server類(lèi)該使用什么類(lèi)加載器?”,這是一個(gè)關(guān)鍵問(wèn)題,因?yàn)樗鼪Q定了使用什么類(lèi)加載器加載整個(gè)Web應(yīng)用程序,也就決定了應(yīng)用程序的運(yùn)行時(shí)應(yīng)該使用和依賴(lài)的類(lèi)路徑,在這種情況下,無(wú)論使用什么類(lèi)加載器加載RunApp腳本,new操作符都會(huì)有效地授權(quán)給

  1. this.getClass().getClassLoader() 

我們的例子是什么意思呢?它意味著生成類(lèi)加載器被用于加載Server類(lèi),因此也必須用于加載Web應(yīng)用程序類(lèi),換句話(huà)說(shuō),所有應(yīng)用程序的運(yùn)行時(shí)依賴(lài)必須包括在生成類(lèi)加載器中。你可能會(huì)問(wèn),這樣會(huì)不會(huì)有問(wèn)題?回答是有一個(gè)潛在的問(wèn)題和一個(gè)實(shí)際的問(wèn)題。
潛在的問(wèn)題是類(lèi)沖突,如果Web應(yīng)用程序依賴(lài)一個(gè)已經(jīng)存在于生成系統(tǒng)中不同版本的庫(kù)會(huì)怎么樣?如果所有Apache XML API庫(kù)都在類(lèi)路徑下,這是一個(gè)特殊的問(wèn)題,絕對(duì)會(huì)導(dǎo)致大破壞。

實(shí)際的問(wèn)題是在類(lèi)路徑中JAR文件越多,JVM尋找類(lèi)的時(shí)間就越長(zhǎng),這意味著啟動(dòng)時(shí)間就越長(zhǎng),這也是OSGi設(shè)計(jì)要解決的問(wèn)題之一,為什么要將JAR放在生成類(lèi)路徑下呢?生成時(shí)本身是不需要它們的。

解決辦法是確定類(lèi)加載器的邊界,使用映射實(shí)例化你的對(duì)象:

  1. def runtimeClassLoader = new URLClassLoader(...)  
  2. def server = runtimeClassLoader.loadClass("org.mortbay.jetty.Server").newInstance()  
  3. ...  
  4. server.start() 



 

責(zé)任編輯:佚名 來(lái)源: 51CTO.com
相關(guān)推薦

2009-08-21 14:16:35

C# New關(guān)鍵字

2023-03-24 08:01:27

Go語(yǔ)言內(nèi)存

2010-01-15 15:45:10

VB.NET New關(guān)

2024-06-04 17:02:38

newC#編程語(yǔ)言

2012-03-13 14:41:41

JavaJVM

2024-03-28 10:40:43

javanew關(guān)鍵字

2024-12-31 00:05:24

new?關(guān)鍵字C#

2009-06-25 10:33:53

StaticJava類(lèi)

2012-06-02 00:53:39

Javafinally

2020-08-10 08:00:13

JavaFinal關(guān)鍵字

2024-04-08 11:35:34

C++static關(guān)鍵字

2022-05-06 08:32:40

Pythonwith代碼

2024-11-20 15:55:57

線(xiàn)程Java開(kāi)發(fā)

2009-09-28 11:34:49

Javascript

2024-12-26 00:28:59

C#base?關(guān)鍵字

2025-01-09 10:30:40

2023-11-19 22:52:42

2012-03-01 12:50:03

Java

2011-06-14 13:26:27

volatile

2017-10-20 11:12:12

數(shù)據(jù)類(lèi)型關(guān)鍵字對(duì)象
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)