最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java基礎(chǔ)之自定義類加載器

 更新時間:2021年05月13日 08:59:57   作者:SmallSweets  
應(yīng)該有很多小伙伴還不了解Java自定義類加載器吧,下文中有對Java自定義類加載器非常詳細(xì)的描述,還有小伙伴們最喜歡的代碼環(huán)節(jié),需要的朋友可以參考下

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

在這里插入圖片描述

自定義類加載器

創(chuàng)建一個類繼承ClassLoader類,同時重寫findClass方法,用于判斷當(dāng)前類的class文件是否已被加載

二、基于本地class文件的自定義類加載器

本地class文件路徑

在這里插入圖片描述

自定義類加載器:

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

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

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

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

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


        if (bytes != null){
//        如果字節(jié)數(shù)組不為空,則將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文件的字節(jié)流
    private byte[] getBytes(String name) throws Exception{
//        拼接class文件路徑 replace(".",File.separator) 表示將全類名中的"."替換為當(dāng)前系統(tǒng)的分隔符,F(xiàn)ile.separator返回當(dāng)前系統(tǒng)的分隔符
        String FileUrl = Path + name.replace(".", File.separator) + ".class";
        byte[] bytes;
//        相當(dāng)于一個緩存區(qū),動態(tài)擴(kuò)容,也就是隨著寫入字節(jié)的增加自動擴(kuò)容
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        File file = new File(FileUrl);
//        創(chuàng)建輸入流
        InputStream inputStream = new FileInputStream(file);
        int content;
//        循環(huán)將輸入流中的所有數(shù)據(jù)寫入到緩存區(qū)中
        while ((content = inputStream.read()) != -1){
            arrayOutputStream.write(content);
            arrayOutputStream.flush();
        }
        bytes = arrayOutputStream.toByteArray();
        return bytes;
    }
}

測試類

在這里插入圖片描述
在這里插入圖片描述

三、遇到的問題

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

在這里插入圖片描述

現(xiàn)在我們嘗試將數(shù)據(jù)直接寫入到bytes中,如下:

在這里插入圖片描述

但在運(yùn)行時報錯:

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

在這里插入圖片描述

這是為什么呢?個人理解如下:

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

查看class文件的大小

在這里插入圖片描述

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

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

在這里插入圖片描述
這樣就可以解決了,雖然可以解決,但如果每次加載類時都要修改未免有些麻煩,所以這里我們直接使用ByteArrayOutputStream,因?yàn)樗莿討B(tài)擴(kuò)容的,也就是大小是隨寫入數(shù)據(jù)的多少而動態(tài)變化的不會出現(xiàn)多余字節(jié)的情況

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

class文件路徑

在這里插入圖片描述

自定義類加載器:

public class MyUrlClassLoader extends ClassLoader {
    private String Path;

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

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

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

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

    }

//    獲取網(wǎng)絡(luò)class文件的字節(jié)流,參數(shù)為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文件的字節(jié)流
        InputStream inputStream = httpURLConnection.getInputStream();
//        相當(dāng)于緩存區(qū),動態(tài)擴(kuò)容
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        int content;
//        循環(huán)將輸入流中的所有數(shù)據(jù)寫入到緩存區(qū)中
        while ((content = inputStream.read()) != -1){
            arrayOutputStream.write(content);
            arrayOutputStream.flush();
        }
        bytes = arrayOutputStream.toByteArray();
        return bytes;
    }

}

測試類

在這里插入圖片描述
在這里插入圖片描述

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

相關(guān)文章

最新評論

垣曲县| 神池县| 昭觉县| 那曲县| 梅河口市| 怀集县| 湘乡市| 丽水市| 巴马| 南澳县| 化州市| 历史| 阳朔县| 神池县| 岢岚县| 丰都县| 新河县| 鹤峰县| 乃东县| 福鼎市| 基隆市| 大洼县| 绍兴市| 来宾市| 本溪| 新乐市| 睢宁县| 济南市| 道孚县| 柞水县| 丹东市| 新泰市| 铜鼓县| 阳新县| 鲁山县| 贺州市| 都匀市| 新乡市| 根河市| 神池县| 绿春县|