国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java自定義類加載器代碼示例

java自定義類加載器代碼示例

2021-03-01 12:17zhangzeyuaaa Java教程

這篇文章主要介紹了java自定義類加載器代碼示例,具有一定借鑒價值,需要的朋友可以了解下。

如果要使用自定義類加載器加載class文件,就需要繼承java.lang.ClassLoader類。

ClassLoader有幾個重要的方法:

protectedClassLoader(ClassLoaderparent):使用指定的、用于委托操作的父類加載器創建新的類加載器。

protectedfinalClass<?>defineClass(Stringname,byte[]b,intoff,intlen):將一個byte數組轉換為Class類的實例。

protectedClass<?>findClass(Stringname):使用指定的二進制名稱查找類。

publicClass<?>loadClass(Stringname):使用指定的二進制名稱來加載類。

protectedfinalClass<?>findLoadedClass(Stringname):如果Java虛擬機已將此加載器記錄為具有給定二進制名稱的某個類的啟動加載器,則返回該二進制名稱的類。否則,返回null。

publicfinalClassLoadergetParent():返回委托的父類加載器。

protectedfinalvoidresolveClass(Class<?>c):鏈接指定的類。

如果要遵循雙親委派模型,則重寫findClass(Stringname)方法;如果不想遵循雙親委派模型,則直接重寫loadClass(Stringname)方法。

自定義遵循雙親委派模型的類加載器

ParentsDelegateClassLoader.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.zzj.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * 雙親委派類加載器,重寫findClass(name)方法
 *
 * @author Administrator
 *
 */
public class ParentsDelegateClassLoader extends ClassLoader {
    private static final String EXT = ".class";
    private String path;
    public ParentsDelegateClassLoader() {
        path = this.getResource("").getPath();
    }
    public ParentsDelegateClassLoader(String path) {
        this.path = path;
    }
    @Override
      protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] b = null;
        try {
            b = loadClassFile(name);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return this.defineClass(name, b, 0, b.length);
    }
    private byte[] loadClassFile(String name) throws IOException {
        String classFile = getClassFile(name);
        System.out.println("即將加載class文件" + classFile);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream input = new FileInputStream(classFile);
        int count;
        byte[] temp = new byte[1024];
        while ((count = input.read(temp)) > -1) {
            out.write(temp, 0, count);
        }
        out.close();
        input.close();
        return out.toByteArray();
    }
    private String getClassFile(String name) {
        String pathName = name.replace(".", File.separator);
        if (path.endsWith("/") || path.endsWith("\\")) {
            return path + pathName + EXT;
        }
        return path + File.separator + pathName + EXT;
    }
}

現在類路徑classpath下和F:\\ClassloaderTest\\bin目錄下都有一個類文件com\zzj\classloader\User.class,包名為com.zzj.classloader,使用類加載器ParentsDelegateClassLoader加載F:\\ClassloaderTest\\bin下的類。

?
1
2
3
4
5
6
7
8
9
10
11
package com.zzj.classloader;
public class App {
    private static final String path = "F:\\ClassloaderTest\\bin";
    private static final String classname = "com.zzj.classloader.User";
    public static void main(String[] args) throws Exception {
        ParentsDelegateClassLoader classLoader = new ParentsDelegateClassLoader(path);
        Class<?> clazz = classLoader.loadClass(classname);
        System.out.println(clazz);
        System.out.println(clazz.getClassLoader());
    }
}

輸出:

?
1
2
class com.zzj.classloader.User
sun.misc.Launcher$AppClassLoader@19821f

User類的加載器是系統類加載器AppClassLoader,而不是我們自己定義的類加載。實際上被加載不是F:\\ClassloaderTest\\bin下的類,而是classpath下的類。這就是雙親委派模型:當ParentsDelegateClassLoader加載器接收到加載請求后,會先委托給父類加載器,如果父類加載器加載成功,則返回一個Class對象。如果加載失敗,才會讓接收到加載請求的類加載器加載。

把classpath下的User類刪掉測試運行:

?
1
2
3
即將加載class文件F:\ClassloaderTest\bin\com\zzj\classloader\User.class
class com.zzj.classloader.User
com.zzj.classloader.ParentsDelegateClassLoader@61de33

此時User類的加載為ParentsDelegateClassLoader。

這一點可以從ClassLoader的源碼中得到驗證:

?
1
2
3
public Class<?> loadClass(String name) throws ClassNotFoundException {
  return loadClass(name, false);
  }

調用了重載方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected synchronized Class<?> loadClass(String name, boolean resolve)
  throws ClassNotFoundException
  {
  // 先判斷該類是否已被當前的類加載器加載
  Class c = findLoadedClass(name);
  if (c == null) {
    try {
    if (parent != null) {// 如果存在父類加載器,則委派給父類加載
      c = parent.loadClass(name, false);
    } else {// 如果父類加載為空,則其父類加載器為引導類加載器
      c = findBootstrapClass0(name);
    }
    } catch (ClassNotFoundException e) {
      // 如果父類加載器加載失敗,則自己加載,調用的就是findClass方法!
      c = findClass(name);
    }
  }
  if (resolve) {
    resolveClass(c);
  }
  return c;
  }

可見,如果想要破壞雙親委派模型,可以直接重寫loadClass(Stringname)方法。

自定義不遵循雙親委派模型的類加載器

NotParentsDelegateClassLoader.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.zzj.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
 * 非雙親委派類加載器,重寫loadClass(name)方法
 *
 * @author Administrator
 *
 */
public class NotParentsDelegateClassLoader extends ClassLoader {
    private static final String EXT = ".class";
    private String path;
    public NotParentsDelegateClassLoader() {
        path = this.getResource("").getPath();
    }
    public NotParentsDelegateClassLoader(String path) {
        this.path = path;
    }
    @Override
      public Class<?> loadClass(String name) throws ClassNotFoundException {
        byte[] b = null;
        try {
            b = loadClassFile(name);
        }
        catch (FileNotFoundException e) {
            System.err.println("加載器" + this.getClass().getName()
                      + "沒有找到class文件" + name + ",將委派給父類加載器!");
            // 委派給父類加載器
            return getClass().getClassLoader().loadClass(name);
        }
        catch (IOException e) {
            System.err.println("加載器" + this.getClass().getName() + "加載class文件"
                      + name + "失敗,將委派給父類加載器!");
            // 委派給父類加載器
            return getClass().getClassLoader().loadClass(name);
        }
        // 檢查該類是否被當前類加載器加載過(只檢查當前類加載器,不會檢查父類加載器)
        Class<?> clazz = findLoadedClass(name);
        if (clazz != null) {
            System.out.println("類" + name + "已被加載過!");
            return clazz;
        } else {
            System.out.println("類" + name + "尚未被加載!");
        }
        return this.defineClass(name, b, 0, b.length);
    }
    private byte[] loadClassFile(String name) throws IOException,
          FileNotFoundException {
        String classFile = getClassFile(name);
        System.out.println("即將加載class文件" + classFile);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream input = new FileInputStream(classFile);
        int count;
        byte[] temp = new byte[1024];
        while ((count = input.read(temp)) > -1) {
            out.write(temp, 0, count);
        }
        out.close();
        input.close();
        return out.toByteArray();
    }
    private String getClassFile(String name) {
        String pathName = name.replace(".", File.separator);
        if (path.endsWith("/") || path.endsWith("\\")) {
            return path + pathName + EXT;
        }
        return path + File.separator + pathName + EXT;
    }
}

現在類路徑classpath下有一個類文件com\zzj\classloader\User.class,包名為com.zzj.classloader,使用類加載器NotParentsDelegateClassLoader加載User類。

?
1
2
3
4
5
6
7
8
9
10
package com.zzj.classloader;
public class App2 {
    private static final String className = "com.zzj.classloader.User";
    public static void main(String[] args) throws Exception {
        NotParentsDelegateClassLoader classLoader = new NotParentsDelegateClassLoader();
        Class<?> clazz = classLoader.loadClass(className);
        System.out.println(clazz);
        System.out.println(clazz.getClassLoader());
    }
}

輸出:

?
1
2
3
4
5
6
即將加載class文件/E:/Myeclipse/zzjtest/WebRoot/WEB-INF/classes/com\zzj\classloader\User.class
類com.zzj.classloader.User尚未被加載!
即將加載class文件/E:/Myeclipse/zzjtest/WebRoot/WEB-INF/classes/java\lang\Object.class
class com.zzj.classloader.User
com.zzj.classloader.NotParentsDelegateClassLoader@61de33
加載器com.zzj.classloader.NotParentsDelegateClassLoader沒有找到class文件java.lang.Object,將委派給父類加載器!

此時User類的加載器是NotParentsDelegateClassLoader,沒有先委托給父類,只有加載失敗才會委托給父類加載器,正好跟雙親委派模型是反的。

當然,即使加載失敗,也可以不委托給父類加載器,而指定其他的類加載器,從而可以構建更加復雜的網狀模型的類加載機制

總結

以上就是本文關于java自定義類加載器代碼示例的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/zhangzeyuaaa/article/details/42527813

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品国产一区二区国模嫣然 | 日韩av免费在线观看 | 国产裸体永久免费视频网站 | 国产一区二区av | 中文字幕 亚洲一区 | 亚洲一区中文字幕在线观看 | 久久久久综合 | 免费一区二区 | 91久久| 国产福利视频在线 | 日韩欧美精品 | 欧美日韩一区二区三区在线观看 | 中文字幕 日韩有码 | 日韩不卡一区二区三区 | 亚洲高清免费视频 | 日韩a∨ | 欧美小电影 | 在线婷婷 | 日韩欧美亚洲 | 中文字幕一区二区三区日韩精品 | 91性高湖久久久久久久久网站 | 天堂俺去俺来也www久久婷婷 | 国产精品久久久久久久久久久久久久久久 | 一级免费视频 | av网站在线播放 | 在线一区二区三区做爰视频网站 | 色在线免费 | 国产一级在线 | 日韩一区二区三区在线视频 | 亚洲精品免费在线观看 | 狠狠综合久久 | 精品久久久久久久久久久久 | 欧美精品三区 | 一级片| 国产免费成人 | 99视频在线免费观看 | 亚洲精品片 | 2018啪一啪| 精品久久伊人 | 成人国产在线 | 青青草99 |