日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

筆者帶你剖析Java7.x新特性

系統 1976 0

前言

最近在ITeye上看見一些朋友正在 激烈 討論關于Java7.x的一些 語法結構 ,所以筆者有些手癢,特此 探尋 了7.x(此篇博文筆者使用的是目前最新版本的JDK-7u15)的一些 新特性 分享給大家。雖然目前很多開發人員至今還在沿用Java4.x(筆者項目至今沿用4.x),但這并不是成為不前進的 借口 。想了解Java的發展,想探尋Java的未來,那么你務必需要時刻保持一顆永不落后的

?

當然筆者此篇博文 不代表官方觀點 ,如果有朋友覺得筆者的話語是妙論,希望指正提出,筆者會在第一時間糾正博文內容。在此筆者先謝過各位利用寶貴的時間閱讀此篇博文,最后筆者祝愿各位新年大吉,工作順利。再次啰嗦一點, SSJ的系列博文,筆者將會在本周更新 ,希望大家體諒。

?

目錄

一、自動資源管理;

二、“<>”類型推斷運算符;

三、字面值下劃線支持;

四、switch字面值支持;

五、聲明二進制字面值;

六、catch表達式調整;

七、文件系統改變;

八、探討Java I/O模型;

九、Swing Framework(JSR 296規范)支持;

十、JVM內核升級之Class Loader架構調整;

十一、JVM內核升級之Garbage Collector調整(時間倉促,后期講解);

?

一、自動資源管理

早在7.x版本之前,某些可回收資源比如:I/O鏈接、DB連接、TCP/UDP連接。開發人員都需要在使用后對其進行 手動 關閉,如果不關閉或者忘記關閉這些資源,就會長期 霸占 JVM內部的資源,極大程度上 影響 了JVM的資源分配。就像內存管理一樣,開發人員夢寐以求的就是希望有一天再也無需關注 繁瑣 的資源管理(資源創建、資源就緒、資源回收)。值得慶幸的是7.x為我們帶來了一次徹頭徹尾改變,我們將再也不必以手動管理我們的資源。

早在Java5.x的時候,Java API為開發人員提供了一個Closeable接口。該接口中包含一個close()方法,允許所有可回收資源的類型對其進行重寫實現。7.x版本中幾乎所有的資源類型都實現了Closeable接口,并重寫了close()方法。也就是說所有可回收的系統資源,我們將 不必 每次使用完后調用close()方法進行資源回收,這一切全部交接給自動資源管理器去做即可。

例如Reader資源類型繼承Closeable接口實現資源自動管理:

      public abstract class Reader implements Readable, Closeable
    

??

當然如果你需要在程序中使用自動資源管理,還需要使用API提供的新語法支持,這類語法包含在try語句塊內部。看到這里你可能不禁感嘆,try也能 支持表達式 了,是的7.x確實允許try使用表達式的 語法方式 實現自動資源管理,但 僅限 于資源類型。

使用try表達式實現自動資源管理:

      try(BufferedReader reader = new BufferedReader(new FileReader("路徑"));)
{
	//...
}
catch(Exception e)
{
	e.printStackTrace();
}
    

??

? 二、“<>”類型推斷運算符

Java 5.x 新增了許多新的功能,在這些新引入的功能中,泛型最為 重要 。泛型是一種新的語法元素,泛型的出現導致整個 Java API 都發生了變化( 比如: Java 集合框架就使用了泛型語法)。

在泛型沒有出現之前,我們都是將 Object 類作為通用的 任意數據類型 使用。因為在 Java 語言中, Object 類是所有類的超類 。但是使用 Object 類作為任意數據類型并不是安全的,因為在很多時候我們需要將 Object 類型向下轉換,在這些轉換過程中偶爾也可能出現 不匹配 的類型轉換錯誤。泛型的出現則很好的解決了 Object 類型所存在的 安全性 問題,且泛型還擴展了代碼的重用性。

泛型的核心概念就是 參數化類型 ,所謂參數化類型指的就是開發人員可以在 外部 指定的數據類型來創建泛型類 泛型接口和泛型方法。

使用泛型類型示例:

      List<String> list = new ArrayList<String>();
    

??

通過上述程序示例我們可以看出,筆者定義了一個泛型類型為String的List集合。這樣一來List集合的泛型參數將會被定義為String類型。但是你有沒有想過,使用里氏替換原則或者實例化泛型類型時,其實現可以簡化泛型類型聲明嗎?答案是肯定的,在Java7.x中,允許使用運算符“<>”來做類型推斷。也就是說你只需要在聲明時標注泛型類型,實現時 無需重復 標注。

使用“<>”類型推斷運算符簡化泛型語法:

      List<String> list = new ArrayList<>();
    

??

三、字面值下劃線支持

不知道大家有沒有過同筆者一樣的煩惱,早在Java7.x版本之前,咱們在定義int或者long類型等變量的字面值時,往往會因為其定義的 值過長 ,從而嚴重影響后續的 可讀性 。如果你也是這么覺得,那么你可以考慮使用Java7.x為字面值操作提供的可讀性優化。那便是允許你直接的字面值中使用符號“_”進行 切分 ,這樣一來不僅可以提升可讀性,還能夠清晰的分辨出字面值的長度。當然程序運行時自然會將“_”符號進行提取再做運算。

使用“_”符號進行字面值可讀性優化:

      int money = 100_000_000;
    

??

四、switch字面值支持

Java一共為開發人員提供了2種多路分支語句,一種是大家常用的if-else,另一種則是switch語句。早在Java7.x版本之前, switch 語句表達式值只能定義 byte short int char等 4 類型,且該語句表達式值 只能 匹配一個 ,故不能重復。但是Java7.x的到來允許switch定義另一種 全新 的表達式值,那就是String類型。

使用String類型作為Switch表達式值:

      switch("a")
{
	case "a":
		System.out.println("a");
		break;
	case "b":
		System.out.println("b");
}
    

?

五、聲明二進制字面值

? Java C 語言、 C++ 語言直接相關。 Java 語言繼承了 C 語言的語法結構,而 OMT(Object Modeling Technique ,對象模型)則是直接從 C++ 語言改編而來的。所以早在 Java7.x 版本之前,開發人員只能夠定義十進制、八進制、十六進制等字面值。但是現在你完全可以使用“ 0b ”字符為 前綴 定義二進制字面值。
定義二進制字面值:

      int test = 0b010101; 
    

?

當然這里筆者需要提示你的是,雖然咱們可以直接在程序中定義二進制字面值。但是在程序運算時,仍然會將其 轉換 成十進制展開運算和輸出。

?

六、catch表達式調整

談到catch語句的時候,不得不提到try語句,因為它們彼此之間存在 相互依賴、相互關聯 的關系。在Java程序中捕獲一個異常采用的是try和catch語句,try語句里面所包含的代碼塊都是需要進行 異常監測 的,而catch語句里面所包含的代碼塊,則是告訴程序當異常發生的時候所需要執行的 異常處理

談到捕獲異常,在Java7.x之前有2種方式。第一種是采用定義多個catch代碼塊,另外一種則是直接使用Exception(可恢復性異常超類)進行捕獲。但是現在,如果你覺得不想 籠統 的將所有異常定義為Exception進行捕獲,或者 糾結 于反復定義catch代碼塊,那么你完全可以采用Java7.x的catch表達式調整。Java7.x允許你在catch表達式內部使用“|”運算符匹配多個異常類型,當觸發異常時,異常類型將自動進行 類型匹配 操作。

使用“|”運算符定義catch表達式:

      try 
{
	//...
}
catch (SQLException | Exception e) 
{
	e.printStackTrace();
}
    

?

七、文件系統改變

既然本章節咱們已經談到了Java的文件系統(FileSystem),那么必然 同樣 也會關聯到I/O技術。其實 所謂 I/O(Input/Outp ut) 指的就是數據輸入 / 輸出的 過程 ,我們稱之為流( 數據通信通道 )這個概念。 比如當 Java 應用程序需要讀取目標數據源的數據時,則開啟輸入流。需要寫入時,則開啟輸出流。數據源允許是本地磁盤、內存或者是網絡中的數據。

向目標數據源讀取數據:

筆者帶你剖析Java7.x新特性

?

向目標數據源寫入數據:

筆者帶你剖析Java7.x新特性

Java的文件系統主要由java.io及java.nio兩個包內的組件 構成 早在Java7.x之前,文件的操作一向都比較 棘手 。當然筆者這里提出的棘手,更多的是指向Java API對文件的管理的 不便 。比如咱們需要編寫一個程序,這個程序的功能僅僅只是拷貝文件后進行粘貼。但就是連這樣簡單的程序邏輯實現,開發人員動則都需要編寫幾十行 有效代碼

使用Java File API操作文件核心示例:

      /* 復制目標數據源數據 */
BufferedInputStream reader = new BufferedInputStream(
		new FileInputStream(COPYFILEPATH));
byte[] content = new byte[reader.available()];
reader.read(content);

/* 將復制數據粘貼至新目錄 */
BufferedOutputStream write = new BufferedOutputStream(
		new FileOutputStream(PASTEFILEPATH));
write.write(content);
    

?

通過上述程序示例我們可以看出,僅僅只是編寫一個簡單的文件復制粘貼邏輯,我們的代碼量都大得 驚人 。如果你也認同上述程序的 繁瑣 ,那么你完全有必要體驗下Java7.x對文件系統的一次全新 改變

Java7.x推出了全新的NIO.2 API以此改變針對文件管理的不便,使得在java.nio.file包下使用 Path、Paths、 Files、 WatchService、 FileSystem 等常用類型可以很好的 簡化 開發人員對文件管理的編碼工作。

咱們就先從Path接口開始進行講解吧。Path接口的 某些功能 其實可以和java.io包下的File類型 等價 ,當然這些功能僅限于 只讀操作 。在實際開發過程中,開發人員可以聯用Path接口和Paths類型,從而獲取文件的一系列上下文信息。

Path接口常用方法如下:

方法名稱 方法返回類型 方法描述
getNameCount() int 獲取當前文件節點數
getFileName() java.nio.file.Path 獲取當前文件名稱
getRoot() java.nio.file.Path 獲取當前文件根目錄
getParent() java.nio.file.Path 獲取當前文件上級關聯目錄

?

聯用Path接口和Paths類型獲取文件信息:

      @Test
public void testFile() {
	Path path = Paths.get("路徑:/文件");
	System.out.println("文件節點數:" + path.getNameCount());   
	System.out.println("文件名稱:" + path.getFileName());   
	System.out.println("文件根目錄:" + path.getRoot());   
	System.out.println("文件上級關聯目錄:" + path.getParent());   
}
    

?

通過上述程序示例我們可以看出,聯用Path接口和Paths類型可以很方便的訪問到目標文件的上下文信息。當然這些操作全都是只讀的,如果開發人員想對文件進行其它 非只讀 操作,比如文件的創建、修改、刪除等操作,則可以使用Files類型進行操作。

Files類型常用方法如下:

方法名稱 方法返回類型 方法描述
createFile() java.nio.file.Path 在指定的目標目錄創建新文件
delete() void 刪除指定目標路徑的文件或文件夾
copy() java.nio.file.Path 將指定目標路徑的文件拷貝到另一個文件中
move() java.nio.file.Path 將指定目標路徑的文件轉移到其他路徑下,并刪除源文件

?

使用Files類型復制、粘貼文件示例:

      Files.copy(Paths.get("路徑:/源文件"), Paths.get("路徑:/新文件"));
    

?

通過上述程序示例我們可以看出,使用Files類型來管理文件,相對于傳統的I/O方式來說更加 方便 簡單 。因為 具體的操作實現將全部移交給NIO.2 API,開發人員則無需關注。

Java7.x還為開發人員提供了一套 全新 的文件系統功能,那就是文件監測。在此或許有很多朋友并不知曉文件監測有何意義及目,那么請大家回想下調試成 熱發布 功能 后的Web容器。當項目迭代后并重新部署時,開發人員無需對其進行手動重啟,因為Web容器一旦監測到文件發生改變后,便會自動去 適應 這些“變化”并重新進行內部 裝載 。Web容器的熱發布功能同樣也是基于文件監測功能,所以不得不承認,文件監測功能的出現對于Java文件系統來說是具有 重大意義 的。

?

提示

就事論事而言,Java7.x的文件監測功能多少存在一些性能和功能上的 缺陷 。但隨著Java后續版本的迭代,筆者相信會有那么一天,足以讓某些整天在論壇上打口水戰的“高手”們閉嘴。

?

如果在程序中需要使用Java7.x的文件監測功能,那么我們務必需要了解 java.nio.file包下的 WatchService接口。 WatchService接口不僅 作為監測服務,還管理著具體的 監控細節

我們可以通過使用 java.nio.file包下的FileSystems類型,并調用FileSystems類型的newWatchService()方法,從而獲取到 WatchService接口的對象實例。

獲取 WatchService接口實例:

      WatchService watchService = FileSystems.getDefault()
		.newWatchService();
    

?

文件監測是基于 件驅動 的,事件觸發是作為監測的 先決條件 。開發人員可以使用java.nio.file包下的StandardWatchEventKinds類型提供的3種字面常量來定義監測事件類型,值得注意的是監測事件需要和 WatchService實例一起進行 注冊

StandardWatchEventKinds類型提供的監測事件:

1、 ENTRY_CREATE:文件或文件夾新建事件

2、 ENTRY_DELETE:文件或文件夾刪除事件

3、 ENTRY_MODIFY:文件或文件夾粘貼事件

?

使用 WatchService類型實現文件監控完整示例:
      @Test
public void testWatch() {
	/* 監控目標路徑 */
	Path path = Paths.get("C:/");
	try {
		/* 創建文件監控對象 */
		WatchService watchService = FileSystems.getDefault()
				.newWatchService();

		/* 注冊文件監控的所有事件類型 */
		path.register(watchService, ENTRY_CREATE, ENTRY_DELETE,
				ENTRY_MODIFY);

		/* 循環監測文件 */
		while (true) {
			WatchKey watchKey = watchService.take();

			/* 迭代觸發事件的所有文件 */
			for (WatchEvent<?> event : watchKey.pollEvents())
				System.out.println(event.context().toString() + " 事件類型:"
						+ event.kind());
			if (!watchKey.reset())
				return;
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}
    

??

通過上述程序示例我們可以看出,使用 WatchService接口 進行文件監控非常簡單和方便。首先我們需要定義好目標監控路徑,然后 調用 FileSystems 類型的newWatchService()方法 創建WatchService對象。接下來我們還需使用Path接口的register()方法注冊WatchService實例及監控事件。當這些基礎作業層全部準備好后,我們再編寫外圍 實時監測 循環。最后迭代WatchKey來獲取所有 觸發 監控事件的文件即可。

?

提示

如果在項目中使用上述程序示例,筆者建議你最好將這段監控代碼進行 異步化 。因為死循環會占用主線程,后續代碼將永遠得不到執行機會。

?

八、探討Java I/O模型

在基于分布式的編程環境中,系統性能的 瓶頸 往往由I/O讀寫性決定。這是不可否認的事實,也是眾多開發人員首要考慮的優化問題。如果在Windows環境下我們使用阻塞I/O模型來編寫分布式應用,其維護成本的往往超出你的想象。因為客戶端的 鏈接數量直接決定了服務器內存開辟的線程數量 * 2 (包含:接受線程、輸出線程),并且這些線程是無法采取線程池優化的,因為線程的執行之間 大于 其創建和銷毀時間。長時間的大量并發線程掛起,不僅CPU要做實時 任務切換 ,其整體物理資源都將一步步被 蠶食 ,直至最后程序崩潰。 在早期的網絡編程中,采取阻塞I/O模型來編寫分布式應用,唯一能做性能優化只有采取傳統的 硬件式堆機 。在付出高昂的硬件成本開銷時,其項目的維護性也令開發人員頭痛。而且在實際的開發過程中,大部分開發人員會選擇將項目部署在Linux下運行。跟Windows 內核結構 不同的是,Linux環境下是沒有真正意義上的線程概念。其所謂的線程都是采用 進程模擬 的方式,也就是 偽線程 。筆者希望大家能夠明白,對于并發要求極高的分布式應用,一旦采用阻塞IO模型編寫就等于自尋死路。

Java的I/O模型由同步I/O和異步I/O構成。同步I/O模型包含:阻塞I/O和非阻塞I/O,而在Windows環境下只要調用了IOCP的I/O模型,就是真正意義上的異步I/O。

Java的I/O模型示例圖:

筆者帶你剖析Java7.x新特性

?

IOCP(Input/Outut Completion Port,輸入/輸出完成端口)簡單來說是一種 系統級 高性能 異步I/O模型。應用程序中所有的I/O操作將全部 委托 給操作系統線程去執行,直至最后通知并返回結果。Java7.x對IOCP進行了 深度封裝 ,這使得開發人員可以使用IOCP API編寫高效的分布式應用。當然IOCP 僅限 于使用在Windows平臺,因而無法在Linux平臺上使用它(Linux平臺上可以通過Epoll模擬IOCP實現)。

?

提示

有過網絡編程經驗的開發人員都應該明白,在Windows平臺下性能最好的I/O模型是IOCP,Linux平臺下則是EPOLL。但是EPOLL并不算真正意義上的異步I/O,EPOLL只是在盡可能的 模擬 IOCP而已。因為按照Unix網絡編程的劃分,多路復用I/O仍然屬于同步I/O模型,也就是說EPOLL其實是屬于多路復用I/O。

簡單來說異步I/O的特征必須滿足如下2點:

1、I/O請求與I/O操作不會阻塞;

2、并非程序自身完成I/O操作,由操作系統線程處理實際的I/O操作,直至最后通知并返回結果;

?

早在Java4.x的時候,NIO(Java New Input/Output,Java新輸入/輸出)的出現,使得開發人員可以徹底從阻塞I/O的 噩夢 中掙脫出來。但編寫NIO的成本較大,學習難度也比較高,使得諸多開發人員望而卻步(目前比較成熟的NIO Frameworks有:Mina、 Netty )。但理解非阻塞I/O的原理還是非常有必要,先來觀察下述采用阻塞I/O模式編寫的分布式應用示例:

      @Test
public void testServer() {
	try {
		ServerSocket server = new ServerSocket(8888);
		Socket clist = server.accept();
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				clist.getInputStream()));
		
		/* 未收到I/O請求時阻塞 */
		System.out.println(reader.readLine());
	} catch (Exception e) {
		e.printStackTrace();
	}
}
    

??

I/O的工作內容我們可以根據其 性質 劃分為2部分:I/O請求和I/O操作。上述程序示例我們采用的是阻塞I/O模型,可以很明確的發現當客戶端成功握手服務端后,如果服務端并沒有收到客戶端的I/O請求,服務端會在reader.readLine()方法處阻塞。直到成功接收到I/O請求后,服務端才會開始執行實際的I/O操作。運用阻塞I/O模式進行分布式編程,為了保證服務端與客戶端集合的成功會話,我們不得不為每一條客戶端連接都開辟獨立的線程執行I/O操作。當然在實際的開發過程中,或許已經沒有開發人員會做這么 荒唐 的事情了。

非阻塞I/O和阻塞I/O最大的不同在于,非阻塞I/O并不會在I/O請求時產生阻塞。也就是說如果服務端沒有收到I/O請求時,非阻塞I/O會 持續輪循 I/O請求,當有請求進來后就開始執行I/O操作并 阻塞請求進程 。Java7.x允許開發人員使用IOCP API進行異步I/O編程,這使得開發人員不必再關心I/O 是否阻塞 。因為應用程序中所有的I/O操作將全部 委托 給操作系統線程去執行,直至最后通知并返回結果。

?

九、Swing Framework(JSR 296規范)支持

筆者其實對Swing 非常厭惡 ,如果可以的話筆者希望Oracle能夠 廢除 掉Swing這項技術。早在08年的時候筆者由于項目需要,曾飽受Swing的折磨。 繁瑣的布局、組件加載優化、冗長代碼維護 這些令人痛苦和發指的問題,筆者相信使用過Swing的人開發人員都能發出相同的感嘆。

早期的Java GUI(圖形用戶界面)主要由AWT技術主導,但隨著用戶對 胖客戶端 技術的豐富度要求逐漸提高,AWT主鍵逐漸被Swing替代。Swing其實繼承于AWT,并提供有更加絢麗的視圖組件效果。何況相對于 重量級 的AWT組件來說,Swing顯得更加 輕量

筆者剛才說過,Swing雖然相對于AWT來說組件內容更加豐富,但仍然掩蓋不了其 繁瑣 的操作實現。如果對組件性能有過高要求,或者需要實現快速開發,筆者更建議你使用SWT或者JFace技術( 無需指望使用IDE工具進行可視化編程,因為這純粹是吃力不討好 )。因為這2種技術可以看成是Swing的過渡,且相對Swing來說性能和豐富度更加優秀。

既然Java7.x對Swing仍不忘眷顧優化,那希望大家還是支持一下吧。從官方聲明可以看出,JSR 296規范的目標是簡化Swing的開發難度,且提供有更加豐富的組件資源。如果對于從未接觸過Swing編程的開發人員,筆者倒是建議你嘗試一下,或許你并不反感。

?

十、JVM內核升級之Class Loader架構調整

類裝載器(Class Loader)屬于JVM體系結構的重要 組成部分 ,它是將Java類型裝載進JVM內部的 關鍵一環 。它使得Java類型可以動態的被裝載到JVM內部解釋并運行。
在JVM內部存在著2種類型的類裝載器:非自定義類裝載器和自定義類裝載器 。非自定義類裝載器負責裝載Java API中的類型及Java程序中的類型,而自定義類裝載器能夠使用自定義的方式來裝載其類型。不同類型的類裝載器所裝載的類型將被存放于JVM內部不同的 命名空間 中。
非自定義類裝載器由JVM內部3個核心類裝載器構成:
1、BootStrap ClassLoader;
2、ExtClassLoader;
3、AppClassLoader;

?

BootStrap ClassLoader也稱為 啟動類裝載器 ,它是JVM內部最 頂層 的類裝載器。BootStrap ClassLoader主要負責裝載核心Java API中的類型。ExtClassLoader負責裝載擴展目錄下的類型。AppClassLoader則負責裝載ClassPath(Java應用類路徑)下指定的所有類型。其中ExtClassLoader和AppClassLoader都屬于BootStrap ClassLoader的 派生 類裝載器。

在Object內部封裝著一個通過JNI(Java Native Interface,Java本地接口)方式調用的getClass()本地方法,該方法返回一個Class類型。對于開發人員而言,允許直接調用其getClassLoader()方法獲取類裝載器實例。

使用getClassLoader()方法獲取類裝載器:

      @Test
public void testClassLoader() throws Exception {
	/* BootStrap ClassLoader裝載Java API中的類型 */
	ClassLoader loader = System.class.getClassLoader();
	System.out.println(null != loader ? loader.getClass().getName()
			: loader);

	/* ExtClassLoader裝載擴展目錄下的類型 */
	System.out.println(CollationData_ar.class.getClassLoader().getClass()
			.getName());

	/* AppClassLoader裝載ClassPath下指定的所有類型 */
	System.out.println(this.getClass().getClassLoader().getClass()
			.getName());
}
    

?

通過上述程序示例我們可以看出,System類型是被BootStrap ClassLoader所裝載的。但程序的輸出結果卻是Null,當然這并不代表BootStrap ClassLoader不存在。因為BootStrap ClassLoader 不是采用Java語言編寫 ,而是由C++語言編寫并 嵌入 在JVM內部,所以開發人員無法獲取其實例。CollationData_ar類型屬于jre\lib\ext目錄下的派生類,由ExtClassLoader裝載。當前類則由AppClassLoader負責裝載。
在此筆者要提示大家,ExtClassLoader和AppClassLoader都是采用Java語言編寫。所以ExtClassLoader和AppClassLoader 本身也都是Java類型 ,都會被最頂層的類裝載器BootStrap ClassLoader裝載,最后才會裝載各自管轄范圍內的類型。
談到ClassLoader的架構,我們不得不提及 雙親委派模型 。在JVM內部,類裝載器裝載類型所采用的便是雙親委派模型機制。比如AppClassLoader需要將一個類型裝載進JVM內部,首先其自身并不會立即裝載,而是將目標類型 委派 給上一級,也就是ExtClassLoader。ExtClassLoader接著再繼續委派給BootStrap ClassLoader。在JVM內部最頂層的類裝載器就是BootStrap ClassLoader,首先由它負責裝載目標類型及其關聯或依賴的所有類型。如果BootStrap ClassLoader裝載失敗,則退回給ExtClassLoader裝載。如果ExtClassLoader也無法裝載,最后只能退回給AppClassLoader繼續裝載。最后當AppClassLoader都無法裝載的時候,便會拋出ClassNotFoundException異常( 開發人員可以在捕獲ClassNotFoundException異常的時候重寫ClassLoder類型的findClass()方法實現自定義類型裝載 )。

類裝載器架構示例:

筆者帶你剖析Java7.x新特性

?

類裝載器除了需要負責類型的裝載,還需要負責驗證目標類型的正確性、屬性內存分配、解析符號引用等操作。JVM通過裝載、連接和初始化一個Java類型,使其可以被運行時的Java應用程序所使用。其中裝載就是把二進制形式的Java類型 寫入 JVM內部。連接則是把已經寫入進JVM中的二進制形式的類型 合并 到JVM的運行時狀態中去。然而連接階段又分成了3個步驟:驗證、準備和解析。“驗證”步驟確保了Java類型的數據格式,“準備”步驟則負責為目標類型分配所需的內存空間,“解析”步驟負責把常量池中的符號引用轉換為直接使用。“驗證”和“解析”這2個步驟都是為最后的初始化工作做準備。

類型生命周期示例:

筆者帶你剖析Java7.x新特性

?

Java7.x在上述ClassLoader架構的基礎之上,進行了一些細微 調整 。在早期開發人員如果想要實現自定義類裝載器,恐怕只能實現ClassLoader類型并重寫其findClass()方法。但由于findClass()方法是按照 串行 結構 的方式執行, 或許是出于對性能和安全的考慮 。Java7.x提供了一個擁有并行執行能力的增強實現,這樣一來自定義類裝載器便可以通過 異步 方式對類型進行裝載。

?

提示

關于自定義類裝載器本章筆者將不再繼續講解,如果有興趣的朋友可以以郵件的形式告知筆者,筆者會為你提供幫助。

?

本章內容到此結束,由于時間倉庫,本文或許有很多不盡人意的地方,希望各位能夠理解和體諒。關于下一章的內容,筆者打算繼續講解SSJ的相關內容。

筆者帶你剖析Java7.x新特性


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 内江市| 固始县| 汶上县| 道孚县| 海丰县| 高淳县| 郧西县| 夹江县| 年辖:市辖区| 兴和县| 北票市| 铜陵市| 通州市| 含山县| 扎兰屯市| 芮城县| 维西| 钟祥市| 黔江区| 奎屯市| 德阳市| 大连市| 大理市| 茌平县| 台安县| 凉城县| 临猗县| 东海县| 新乡市| 洪江市| 广南县| 时尚| 额济纳旗| 锡林郭勒盟| 莎车县| 安图县| 尚义县| 奎屯市| 安徽省| 扎赉特旗| 德江县|