欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
了解Java ClassLoader
【原文地址:https://www6.software.ibm.com/developerworks/cn/education/java/j-classloader/tutorial/】
1.介紹
2.ClassLoader的結構
3.Compiling ClassLoader
4.java2 中ClassLoader的變動(dòng)
5.源代碼
---------------------------------------------------------------------------

第一章 介紹

什么是 ClassLoader

在流行的商業(yè)化編程語(yǔ)言中,Java 語(yǔ)言由于在 Java 虛擬機 (JVM) 上運行而顯得與眾不同。這意味著(zhù)已編譯的程序是一種特殊的、獨立于平臺的格式,并非依賴(lài)于它們所運行的機器。在很大程度上,這種格式不同于傳統的可執行程序格式。

與 C 或 C++ 編寫(xiě)的程序不同,Java 程序并不是一個(gè)可執行文件,而是由許多獨立的類(lèi)文件組成,每一個(gè)文件對應于一個(gè) Java 類(lèi)。

此外,這些類(lèi)文件并非立即全部都裝入內存,而是根據程序需要裝入內存。ClassLoader 是 JVM 中將類(lèi)裝入內存的那部分。

而且,Java ClassLoader 就是用 Java 語(yǔ)言編寫(xiě)的。這意味著(zhù)創(chuàng )建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小細節。

為什么編寫(xiě) ClassLoader?

如果 JVM 已經(jīng)有一個(gè) ClassLoader,那么為什么還要編寫(xiě)另一個(gè)呢?問(wèn)得好。缺省的 ClassLoader 只知道如何從本地文件系統裝入類(lèi)文件。不過(guò)這只適合于常規情況,即已全部編譯完 Java 程序,并且計算機處于等待狀態(tài)。

但 Java 語(yǔ)言最具新意的事就是 JVM 可以非常容易地從那些非本地硬盤(pán)或從網(wǎng)絡(luò )上獲取類(lèi)。例如,瀏覽者可以使用定制的 ClassLoader 從 Web 站點(diǎn)裝入可執行內容。

有許多其它方式可以獲取類(lèi)文件。除了簡(jiǎn)單地從本地或網(wǎng)絡(luò )裝入文件以外,可以使用定制的 ClassLoader 完成以下任務(wù):

  • 在執行非置信代碼之前,自動(dòng)驗證數字簽名
  • 使用用戶(hù)提供的密碼透明地解密代碼
  • 動(dòng)態(tài)地創(chuàng )建符合用戶(hù)特定需要的定制化構建類(lèi)
任何您認為可以生成 Java 字節碼的內容都可以集成到應用程序中。

定制 ClassLoader 示例

如果使用過(guò) JDK 或任何基于 Java 瀏覽器中的 Applet 查看器,那么您差不多肯定使用過(guò)定制的 ClassLoader。

Sun 最初發(fā)布 Java 語(yǔ)言時(shí),其中最令人興奮的一件事是觀(guān)看這項新技術(shù)是如何執行在運行時(shí)從遠程的 Web 服務(wù)器裝入的代碼。(此外,還有更令人興奮的事 -- Java 技術(shù)提供了一種便于編寫(xiě)代碼的強大語(yǔ)言。)更一些令人激動(dòng)的是它可以執行從遠程 Web 服務(wù)器通過(guò) HTTP 連接發(fā)送過(guò)來(lái)的字節碼。

此 項功能歸功于 Java 語(yǔ)言可以安裝定制 ClassLoader。Applet 查看器包含一個(gè) ClassLoader,它不在本地文件系統中尋找類(lèi),而是訪(fǎng)問(wèn)遠程服務(wù)器上的 Web 站點(diǎn),經(jīng)過(guò) HTTP 裝入原始的字節碼文件,并把它們轉換成 JVM 內的類(lèi)。

瀏覽器和 Applet 查看器中的 ClassLoaders 還可以做其它事情:它們支持安全性以及使不同的 Applet 在不同的頁(yè)面上運行而互不干擾。

Luke Gorrie 編寫(xiě)的 Echidna 是一個(gè)開(kāi)放源碼包,它可以使您在單個(gè)虛擬機上運行多個(gè) Java 應用程序。(請參閱進(jìn)一步了解和參考資料。)它使用定制的 ClassLoader,通過(guò)向每個(gè)應用程序提供該類(lèi)文件的自身副本,以防止應用程序互相干擾。


我們的 ClassLoader 示例

了解了 ClassLoader 如何工作以及如何編寫(xiě) ClassLoader 之后,我們將創(chuàng )建稱(chēng)作 CompilingClassLoader (CCL) 的 Classloader。CCL 為我們編譯 Java 代碼,而無(wú)需要我們干涉這個(gè)過(guò)程。它基本上就類(lèi)似于直接構建到運行時(shí)系統中的 "make" 程序。

注:進(jìn)一步了解之前,應注意在 JDK 版本 1.2 中已改進(jìn)了 ClassLoader 系統的某些方面(即 Java 2 平臺)。本教程是按 JDK 版本 1.0 和 1.1 寫(xiě)的,但也可以在以后的版本中運行。

Java 2 中 ClassLoader 的變動(dòng)描述了 Java 版本 1.2 中的變動(dòng),并提供了一些詳細信息,以便修改 ClassLoader 來(lái)利用這些變動(dòng)。

 


 

------------------------------------------------------------------------------------------------------

第二章.ClassLoader的結構



ClassLoader 的基本目標是對類(lèi)的請求提供服務(wù)。當 JVM 需要使用類(lèi)時(shí),它根據名稱(chēng)向 ClassLoader 請求這個(gè)類(lèi),然后 ClassLoader 試圖返回一個(gè)表示這個(gè)類(lèi)的 Class 對象。

通過(guò)覆蓋對應于這個(gè)過(guò)程不同階段的方法,可以創(chuàng )建定制的 ClassLoader。

在本章的其余部分,您會(huì )學(xué)習 Java ClassLoader 的關(guān)鍵方法。您將了解每一個(gè)方法的作用以及它是如何適合裝入類(lèi)文件這個(gè)過(guò)程的。您也會(huì )知道,創(chuàng )建自己的 ClassLoader 時(shí),需要編寫(xiě)什么代碼。

在下一章中,您將會(huì )利用這些知識來(lái)使用我們的 ClassLoader 示例 -- CompilingClassLoader。


方法 loadClass


ClassLoader.loadClass() 是 ClassLoader 的入口點(diǎn)。其特征如下:

 

Class loadClass( String name, boolean resolve );

name 參數指定了 JVM 需要的類(lèi)的名稱(chēng),該名稱(chēng)以包表示法表示,如 Foojava.lang.Object。

resolve 參數告訴方法是否需要解析類(lèi)。在準備執行類(lèi)之前,應考慮類(lèi)解析。并不總是需要解析。如果 JVM 只需要知道該類(lèi)是否存在或找出該類(lèi)的超類(lèi),那么就不需要解析。

在 Java 版本 1.1 和以前的版本中,loadClass 方法是創(chuàng )建定制的 ClassLoader 時(shí)唯一需要覆蓋的方法。(Java 2 中 ClassLoader 的變動(dòng)提供了關(guān)于 Java 1.2 中 findClass() 方法的信息。)


方法 defineClass

defineClass 方法是 ClassLoader 的主要訣竅。該方法接受由原始字節組成的數組并把它轉換成 Class 對象。原始數組包含如從文件系統或網(wǎng)絡(luò )裝入的數據。

defineClass 管理 JVM 的許多復雜、神秘和倚賴(lài)于實(shí)現的方面 -- 它把字節碼分析成運行時(shí)數據結構、校驗有效性等等。不必擔心,您無(wú)需親自編寫(xiě)它。事實(shí)上,即使您想要這么做也不能覆蓋它,因為它已被標記成最終的。


方法 findSystemClass

findSystemClass 方法從本地文件系統裝入文件。它在本地文件系統中尋找類(lèi)文件,如果存在,就使用 defineClass 將原始字節轉換成 Class 對象,以將該文件轉換成類(lèi)。當運行 Java 應用程序時(shí),這是 JVM 正常裝入類(lèi)的缺省機制。(Java 2 中 ClassLoader 的變動(dòng)提供了關(guān)于 Java 版本 1.2 這個(gè)過(guò)程變動(dòng)的詳細信息。)

對于定制的 ClassLoader,只有在嘗試其它方法裝入類(lèi)之后,再使用 findSystemClass。原因很簡(jiǎn)單:ClassLoader 是負責執行裝入類(lèi)的特殊步驟,不是負責所有類(lèi)。例如,即使 ClassLoader 從遠程的 Web 站點(diǎn)裝入了某些類(lèi),仍然需要在本地機器上裝入大量的基本 Java 庫。而這些類(lèi)不是我們所關(guān)心的,所以要 JVM 以缺省方式裝入它們:從本地文件系統。這就是 findSystemClass 的用途。

其工作流程如下:

 

  • 請求定制的 ClassLoader 裝入類(lèi)。
  • 檢查遠程 Web 站點(diǎn),查看是否有所需要的類(lèi)。
  • 如果有,那么好;抓取這個(gè)類(lèi),完成任務(wù)。
  • 如果沒(méi)有,假定這個(gè)類(lèi)是在基本 Java 庫中,那么調用 findSystemClass,使它從文件系統裝入該類(lèi)。

在大多數定制 ClassLoaders 中,首先調用 findSystemClass 以節省在本地就可以裝入的許多 Java 庫類(lèi)而要在遠程 Web 站點(diǎn)上查找所花的時(shí)間。然而,正如,在下一章節所看到的,直到確信能自動(dòng)編譯我們的應用程序代碼時(shí),才讓 JVM 從本地文件系統裝入類(lèi)。


方法 resolveClass

正如前面所提到的,可以不完全地(不帶解析)裝入類(lèi),也可以完全地(帶解析)裝入類(lèi)。當編寫(xiě)我們自己的 loadClass 時(shí),可以調用 resolveClass,這取決于 loadClassresolve 參數的值。

方法 findLoadedClass

findLoadedClass 充當一個(gè)緩存:當請求 loadClass 裝入類(lèi)時(shí),它調用該方法來(lái)查看 ClassLoader 是否已裝入這個(gè)類(lèi),這樣可以避免重新裝入已存在類(lèi)所造成的麻煩。應首先調用該方法。

組裝

 

 

 

讓我們看一下如何組裝所有方法。

我們的 loadClass 實(shí)現示例執行以下步驟。(這里,我們沒(méi)有指定生成類(lèi)文件是采用了哪種技術(shù) -- 它可以是從 Net 上裝入、或者從歸檔文件中提取、或者實(shí)時(shí)編譯。無(wú)論是哪一種,那是種特殊的神奇方式,使我們獲得了原始類(lèi)文件字節。)

 

  • 調用 findLoadedClass 來(lái)查看是否存在已裝入的類(lèi)。

  • 如果沒(méi)有,那么采用那種特殊的神奇方式來(lái)獲取原始字節。

  • 如果已有原始字節,調用 defineClass 將它們轉換成 Class 對象。

  • 如果沒(méi)有原始字節,然后調用 findSystemClass 查看是否從本地文件系統獲取類(lèi)。

  • 如果 resolve 參數是 true,那么調用 resolveClass 解析 Class 對象。

  • 如果還沒(méi)有類(lèi),返回 ClassNotFoundException。

  • 否則,將類(lèi)返回給調用程序。
推想

現在您已經(jīng)了解了 ClassLoader 的工作原理,現在該構建一個(gè)了。在下一章中,我們將討論 CCL。

---------------------------------------------------------------------------------------------

第三章:Compiling ClassLoader

CCL 揭密

我們的 ClassLoader (CCL) 的任務(wù)是確保代碼被編譯和更新。

下面描述了它的工作方式:

 

  • 當請求一個(gè)類(lèi)時(shí),先查看它是否在磁盤(pán)的當前目錄或相應的子目錄。

  • 如果該類(lèi)不存在,但源碼中有,那么調用 Java 編譯器來(lái)生成類(lèi)文件。

  • 如果該類(lèi)已存在,檢查它是否比源碼舊。如果是,調用 Java 編譯器來(lái)重新生成類(lèi)文件。

  • 如果編譯失敗,或者由于其它原因不能從現有的源碼中生成類(lèi)文件,返回 ClassNotFoundException。

  • 如果仍然沒(méi)有該類(lèi),也許它在其它庫中,所以調用 findSystemClass 來(lái)尋找該類(lèi)。

  • 如果還是沒(méi)有,則返回 ClassNotFoundException。

  • 否則,返回該類(lèi)。
Java 編譯的工作方式

 

在深入討論之前,應該先退一步,討論 Java 編譯。通常,Java 編譯器不只是編譯您要求它編譯的類(lèi)。它還會(huì )編譯其它類(lèi),如果這些類(lèi)是您要求編譯的類(lèi)所需要的類(lèi)。

CCL 逐個(gè)編譯應用程序中的需要編譯的每一個(gè)類(lèi)。但一般來(lái)說(shuō),在編譯器編譯完第一個(gè)類(lèi)后,CCL 會(huì )查找所有需要編譯的類(lèi),然后編譯它。為什么?Java 編譯器類(lèi)似于我們正在使用的規則:如果類(lèi)不存在,或者與它的源碼相比,它比較舊,那么它需要編譯。其實(shí),Java 編譯器在 CCL 之前的一個(gè)步驟,它會(huì )做大部分的工作。

當 CCL 編譯它們時(shí),會(huì )報告它正在編譯哪個(gè)應用程序上的類(lèi)。在大多數的情況下,CCL 會(huì )在程序中的主類(lèi)上調用編譯器,它會(huì )做完所有要做的 -- 編譯器的單一調用已足夠了。

然而,有一種情形,在第一步時(shí)不會(huì )編譯某些類(lèi)。如果使用 Class.forName 方法,通過(guò)名稱(chēng)來(lái)裝入類(lèi),Java 編譯器會(huì )不知道這個(gè)類(lèi)時(shí)所需要的。在這種情況下,您會(huì )看到 CCL 再次運行 Java 編譯器來(lái)編譯這個(gè)類(lèi)。在源代碼中演示了這個(gè)過(guò)程。

使用 CompilationClassLoader

要使用 CCL,必須以特殊方式調用程序。不能直接運行該程序,如:

 

% java Foo arg1 arg2

應以下列方式運行它:

 

% java CCLRun Foo arg1 arg2

CCLRun 是一個(gè)特殊的存根程序,它創(chuàng )建 CompilingClassLoader 并用它來(lái)裝入程序的主類(lèi),以確保通過(guò) CompilingClassLoader 來(lái)裝入整個(gè)程序。CCLRun 使用 Java Reflection API 來(lái)調用特定類(lèi)的主方法并把參數傳遞給它。有關(guān)詳細信息,請參閱源代碼。

運行示例

源碼包括了一組小類(lèi),它們演示了工作方式。主程序是 Foo 類(lèi),它創(chuàng )建類(lèi) Bar 的實(shí)例。類(lèi) Bar 創(chuàng )建另一個(gè)類(lèi) Baz 的實(shí)例,它在 baz 包內,這是為了展示 CCL 是如何處理子包里的代碼。Bar 也是通過(guò)名稱(chēng)裝入的,其名稱(chēng)為 Boo,這用來(lái)展示它也能與 CCL 工作。

每個(gè)類(lèi)都聲明已被裝入并運行?,F在用源代碼來(lái)試一下。編譯 CCLRun 和 CompilingClassLoader。確保不要編譯其它類(lèi)(Foo、Bar、BazBoo),否則將不會(huì )使用 CCL,因為這些類(lèi)已經(jīng)編譯過(guò)了。

 



% java CCLRun Foo arg1 arg2

CCL: Compiling Foo.java...

foo! arg1 arg2

bar! arg1 arg2

baz! arg1 arg2

CCL: Compiling Boo.java...

Boo!

請注意,首先調用編譯器,Foo.java 管理 Barbaz.Baz。直到 Bar 通過(guò)名稱(chēng)來(lái)裝入 Boo 時(shí),被調用它,這時(shí) CCL 會(huì )再次調用編譯器來(lái)編譯它。

 

 

 

 

--------------------------------------------------------------------------------------

第四章:java2 中ClassLoader的變動(dòng)


概述

在 Java 版本 1.2 和以后的版本中,對 ClassLoader 做了一些改進(jìn)。任何為老系統編寫(xiě)的代碼可以在新版本中運行,但新系統為您提供了一些便利。

新模型是委托模型,這意味著(zhù)如果 ClassLoader 不能找到類(lèi),它會(huì )請求父代 ClassLoader 來(lái)執行此項任務(wù)。所有 ClassLoaders 的根是系統 ClassLoader,它會(huì )以缺省方式裝入類(lèi) -- 即,從本地文件系統。

loadClass 的缺省實(shí)現

定制編寫(xiě)的 loadClass 方法一般嘗試幾種方式來(lái)裝入所請求的類(lèi),如果您編寫(xiě)許多類(lèi),會(huì )發(fā)現一次次地在相同的、很復雜的方法上編寫(xiě)變量。

在 Java 1.2 中 loadClass 的實(shí)現嵌入了大多數查找類(lèi)的一般方法,并使您通過(guò)覆蓋 findClass 方法來(lái)定制它,在適當的時(shí)候 findClass 會(huì )調用 loadClass。

這種方式的好處是您可能不一定要覆蓋 loadClass;只要覆蓋 findClass 就行了,這減少了工作量。

新方法:findClass

loadClass 的缺省實(shí)現調用這個(gè)新方法。findClass 的用途包含您的 ClassLoader 的所有特殊代碼,而無(wú)需要復制其它代碼(例如,當專(zhuān)門(mén)的方法失敗時(shí),調用系統 ClassLoader)。

新方法:getSystemClassLoader

如果覆蓋 findClassloadClass,getSystemClassLoader 使您能以實(shí)際 ClassLoader 對象來(lái)訪(fǎng)問(wèn)系統 ClassLoader(而不是固定的從 findSystemClass 調用它)。

新方法:getParent

為了將類(lèi)請求委托給父代 ClassLoader,這個(gè)新方法允許 ClassLoader 獲取它的父代 ClassLoader。當使用特殊方法,定制的 ClassLoader 不能找到類(lèi)時(shí),可以使用這種方法。

父代 ClassLoader 被定義成創(chuàng )建該 ClassLoader 所包含代碼的對象的 ClassLoader。

----------------------------------------------------------------------------------

 

 

 

第五章.源代碼

 

CompilingClassLoader.java

以下是 CompilingClassLoader.java 的源代碼

// $Id$

import java.io.*;

/*

A CompilingClassLoader compiles your Java source on-the-fly. It checks

for nonexistent .class files, or .class files that are older than their

corresponding source code.*/

public class CompilingClassLoader extends ClassLoader

{

// Given a filename, read the entirety of that file from disk

// and return it as a byte array.

private byte[] getBytes( String filename ) throws IOException {

// Find out the length of the file

File file = new File( filename );

long len = file.length();

// Create an array that‘s just the right size for the file‘s

// contents

byte raw[] = new byte[(int)len];

// Open the file

FileInputStream fin = new FileInputStream( file );

// Read all of it into the array; if we don‘t get all,

// then it‘s an error.

int r = fin.read( raw );

if (r != len)

throw new IOException( "Can‘t read all, "+r+" != "+len );

// Don‘t forget to close the file!

fin.close();

// And finally return the file contents as an array

return raw;

}

// Spawn a process to compile the java source code file

// specified in the ‘javaFile‘ parameter. Return a true if

// the compilation worked, false otherwise.

private boolean compile( String javaFile ) throws IOException {

// Let the user know what‘s going on

System.out.println( "CCL: Compiling "+javaFile+"..." );

// Start up the compiler

Process p = Runtime.getRuntime().exec( "javac "+javaFile );

// Wait for it to finish running

try {

p.waitFor();

} catch( InterruptedException ie ) { System.out.println( ie ); }

// Check the return code, in case of a compilation error

int ret = p.exitValue();

// Tell whether the compilation worked

return ret==0;

}

// The heart of the ClassLoader -- automatically compile

// source as necessary when looking for class files

public Class loadClass( String name, boolean resolve )

throws ClassNotFoundException {



// Our goal is to get a Class object

Class clas = null;



// First, see if we‘ve already dealt with this one

clas = findLoadedClass( name );



//System.out.println( "findLoadedClass: "+clas );



// Create a pathname from the class name

// E.g. java.lang.Object => java/lang/Object

String fileStub = name.replace( ‘.‘, ‘/‘ );



// Build objects pointing to the source code (.java) and object

// code (.class)

String javaFilename = fileStub+".java";

String classFilename = fileStub+".class";



File javaFile = new File( javaFilename );

File classFile = new File( classFilename );



//System.out.println( "j "+javaFile.lastModified()+" c "+

// classFile.lastModified() );



// First, see if we want to try compiling. We do if (a) there

// is source code, and either (b0) there is no object code,

// or (b1) there is object code, but it‘s older than the source

if (javaFile.exists() &&

(!classFile.exists() ||

javaFile.lastModified() > classFile.lastModified())) {



try {

// Try to compile it. If this doesn‘t work, then

// we must declare failure. (It‘s not good enough to use

// and already-existing, but out-of-date, classfile)

if (!compile( javaFilename ) || !classFile.exists()) {

throw new ClassNotFoundException( "Compile failed: "+javaFilename );

}

} catch( IOException ie ) {



// Another place where we might come to if we fail

// to compile

throw new ClassNotFoundException( ie.toString() );

}

}



// Let‘s try to load up the raw bytes, assuming they were

// properly compiled, or didn‘t need to be compiled

try {



// read the bytes

byte raw[] = getBytes( classFilename );



// try to turn them into a class

clas = defineClass( name, raw, 0, raw.length );

} catch( IOException ie ) {

// This is not a failure! If we reach here, it might

// mean that we are dealing with a class in a library,

// such as java.lang.Object

}



//System.out.println( "defineClass: "+clas );



// Maybe the class is in a library -- try loading

// the normal way

if (clas==null) {

clas = findSystemClass( name );

}



//System.out.println( "findSystemClass: "+clas );



// Resolve the class, if any, but only if the "resolve"

// flag is set to true

if (resolve && clas != null)

resolveClass( clas );



// If we still don‘t have a class, it‘s an error

if (clas == null)

throw new ClassNotFoundException( name );



// Otherwise, return the class

return clas;

}


 }

CCRun.java




以下是 CCRun.java 的源代碼




// $Id$



import java.lang.reflect.*;



/*



CCLRun executes a Java program by loading it through a

CompilingClassLoader.



*/



public class CCLRun

{

static public void main( String args[] ) throws Exception {



// The first argument is the Java program (class) the user

// wants to run

String progClass = args[0];



// And the arguments to that program are just

// arguments 1..n, so separate those out into

// their own array

String progArgs[] = new String[args.length-1];

System.arraycopy( args, 1, progArgs, 0, progArgs.length );



// Create a CompilingClassLoader

CompilingClassLoader ccl = new CompilingClassLoader();



// Load the main class through our CCL

Class clas = ccl.loadClass( progClass );



// Use reflection to call its main() method, and to

// pass the arguments in.



// Get a class representing the type of the main method‘s argument

Class mainArgType[] = { (new String[0]).getClass() };



// Find the standard main method in the class

Method main = clas.getMethod( "main", mainArgType );



// Create a list containing the arguments -- in this case,

// an array of strings

Object argsArray[] = { progArgs };



// Call the method

main.invoke( null, argsArray );

}

}

Foo.java




以下是 Foo.java 的源代碼






// $Id$



public class Foo

{

static public void main( String args[] ) throws Exception {

System.out.println( "foo! "+args[0]+" "+args[1] );

new Bar( args[0], args[1] );

}

}

Bar.java




以下是 Bar.java 的源代碼




// $Id$



import baz.*;



public class Bar

{

public Bar( String a, String b ) {

System.out.println( "bar! "+a+" "+b );

new Baz( a, b );



try {

Class booClass = Class.forName( "Boo" );

Object boo = booClass.newInstance();

} catch( Exception e ) {

e.printStackTrace();

}

}

}

baz/Baz.java




以下是 baz/Baz.java 的源代碼




// $Id$



package baz;



public class Baz

{

public Baz( String a, String b ) {

System.out.println( "baz! "+a+" "+b );

}

}



Boo.java




以下是 Boo.java 的源代碼




// $Id$



public class Boo

{

public Boo() {

System.out.println( "Boo!" );

}

}










本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
初探Java類(lèi)加載機制的奧秘 轉載天極網(wǎng)blog
關(guān)于class.forname和contextClassloader
談java中類(lèi)的加載、鏈接和初始化
使用自己的類(lèi)別載入器
JAR運行出現ClassNotFoundException異常的解決辦法
JAVA類(lèi)的靜態(tài)加載和動(dòng)態(tài)加載以及NoClassDefFoundError和ClassNotFoundException
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久