国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Java基礎之自定義類(lèi)加載器

發(fā)布時(shí)間:2021-07-06 11:13 來(lái)源:腳本之家 閱讀:0 作者:SmallSweets 欄目: 開(kāi)發(fā)技術(shù)

目錄

一、類(lèi)加載器關(guān)系

自定義類(lèi)加載器

創(chuàng )建一個(gè)類(lèi)繼承ClassLoader類(lèi),同時(shí)重寫(xiě)findClass方法,用于判斷當前類(lèi)的class文件是否已被加載

二、基于本地class文件的自定義類(lèi)加載器

本地class文件路徑

自定義類(lèi)加載器:

//創(chuàng  )建自定義加載器類(lèi)繼承ClassLoader類(lèi)
public class MyClassLoader extends ClassLoader{
//    包路徑
    private String Path;

//    構造方法,用于初始化Path屬性
    public MyClassLoader(String path) {
        this.Path = path;
    }

//    重寫(xiě)findClass方法,參數name表示要加載類(lèi)的全類(lèi)名(包名.類(lèi)名)
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println("findclass方法執行");

//        檢查該類(lèi)的class文件是否已被加載,如果已加載則返回class文件(字節碼文件)對象,如果沒(méi)有加載返回null
        Class<?> loadedClass = findLoadedClass(name);
//        如果已加載直接返回該類(lèi)的class文件(字節碼文件)對象
        if (loadedClass != null){
            return loadedClass;
        }

//        字節數組,用于存儲class文件的字節流
        byte[] bytes = null;
        try {
//            獲取class文件的字節流
            bytes = getBytes(name);
        } catch (Exception e) {
            e.printStackTrace();
        }


        if (bytes != null){
//        如果字節數組不為空,則將class文件加載到JVM中
            System.out.println(bytes.length);
//            將class文件加載到JVM中,返回class文件對象
            Class<?> aClass = this.defineClass(name, bytes, 0, bytes.length);
            return aClass;
        }else {
            throw new ClassNotFoundException();
        }
    }

//    獲取class文件的字節流
    private byte[] getBytes(String name) throws Exception{
//        拼接class文件路徑 replace(".",File.separator) 表示將全類(lèi)名中的"."替換為當前系統的分隔符,File.separator返回當前系統的分隔符
        String FileUrl = Path + name.replace(".", File.separator) + ".class";
        byte[] bytes;
//        相當于一個(gè)緩存區,動(dòng)態(tài)擴容,也就是隨著(zhù)寫(xiě)入字節的增加自動(dòng)擴容
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        File file = new File(FileUrl);
//        創(chuàng  )建輸入流
        InputStream inputStream = new FileInputStream(file);
        int content;
//        循環(huán)將輸入流中的所有數據寫(xiě)入到緩存區中
        while ((content = inputStream.read()) != -1){
            arrayOutputStream.write(content);
            arrayOutputStream.flush();
        }
        bytes = arrayOutputStream.toByteArray();
        return bytes;
    }
}

測試類(lèi)


三、遇到的問(wèn)題

在獲取class文件字節流的getBytes方法中,為什么不將輸入流中的所有數據直接寫(xiě)入到bytes中,而是要先寫(xiě)入到ByteArrayOutputStream中?如下:

現在我們嘗試將數據直接寫(xiě)入到bytes中,如下:

但在運行時(shí)報錯:

Extra bytes at the end of class file com/smallsweets/OutSide

這是為什么呢?個(gè)人理解如下:

看報錯提示Extra bytes at the end of:在文件的最后有多余的字節

查看class文件的大小

但是字節數組在初始化時(shí)指定的大小是1024,多余位置的字節是0,所以就出現了多余字節的情況

解決方法是:我們可以在初始化數組時(shí)將數組的大小指定為和class文件相同大小,如下:


這樣就可以解決了,雖然可以解決,但如果每次加載類(lèi)時(shí)都要修改未免有些麻煩,所以這里我們直接使用ByteArrayOutputStream,因為它是動(dòng)態(tài)擴容的,也就是大小是隨寫(xiě)入數據的多少而動(dòng)態(tài)變化的不會(huì )出現多余字節的情況

四、基于網(wǎng)絡(luò )(url)class文件的自定義類(lèi)加載器

class文件路徑

自定義類(lèi)加載器:

public class MyUrlClassLoader extends ClassLoader {
    private String Path;

    public MyUrlClassLoader(String path) {
        this.Path = path;
    }

//    參數name表示全類(lèi)名(包名.類(lèi)名)
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
//        判斷該類(lèi)的class文件是否已加載,已加載直接返回class文件對象,沒(méi)有加載返回null
        Class<?> loadedClass = this.findLoadedClass(name);
        if (loadedClass != null){
            return  loadedClass;
        }

        byte[] bytes = null;
        try {
//            獲取網(wǎng)絡(luò )class文件的字節數組
            bytes = getBytes(Path);
        } catch (Exception e) {
            e.printStackTrace();
        }

//        如果字節數組不為空,將class文件加載到JVM中
        if (bytes != null){
//            將class文件加載到JVM中,參數(全類(lèi)名,字節數組,起始位置,長(cháng)度)
            Class<?> aClass = this.defineClass(name, bytes, 0, bytes.length);
            return aClass;
        }else {
            throw new ClassNotFoundException();
        }

    }

//    獲取網(wǎng)絡(luò )class文件的字節流,參數為class文件的url
    private byte[] getBytes(String fileUrl) throws Exception {
        byte[] bytes;
//        創(chuàng  )建url對象
        URL url = new URL(fileUrl);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//        連接url
        httpURLConnection.connect();
//        創(chuàng  )建輸入流,獲取網(wǎng)絡(luò )中class文件的字節流
        InputStream inputStream = httpURLConnection.getInputStream();
//        相當于緩存區,動(dòng)態(tài)擴容
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        int content;
//        循環(huán)將輸入流中的所有數據寫(xiě)入到緩存區中
        while ((content = inputStream.read()) != -1){
            arrayOutputStream.write(content);
            arrayOutputStream.flush();
        }
        bytes = arrayOutputStream.toByteArray();
        return bytes;
    }

}

測試類(lèi)


到此這篇關(guān)于Java基礎之自定義類(lèi)加載器的文章就介紹到這了,更多相關(guān)Java自定義類(lèi)加載器內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

日韩AV一区二区三区免费看| 级毛片内射视频| 欧美黑人巨大xxxxx视频 | 中文字幕人成乱码熟女| 最近中文字幕MV在线视频WWW| 久久亚洲AV成人无码|