1. 程式人生 > >簡單的自定義類載入器

簡單的自定義類載入器

package com.java.basic.classloaders;

import java.io.*;

public class FileSystemClassLoader extends ClassLoader{

    private String dirPath;

    public FileSystemClassLoader(String dirPath) {
        this.dirPath = dirPath;
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        /**
         * 1. 先獲取是否已經被載入
         * 2. 無
         *  1. 使用雙親委託機制
         *  2. 失敗
         *   1. 自己載入
         */
        Class targetC = null;
        targetC = findLoadedClass(name);
        if (targetC != null) return targetC;
        try {
            targetC = getParent().loadClass(name);
        } catch (ClassNotFoundException e) {
        }
        if (targetC == null) {
            try {
                byte[] bytes = dataBytes(name);
                targetC = defineClass(name, bytes, 0, bytes.length);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return targetC;
    }

    private byte[] dataBytes(String name) throws IOException {
        String path = dirPath + "/" + name.replaceAll("\\.", "/") + ".class";
        // 獲取該檔案的流, 並獲取其位元組碼陣列資料
        InputStream in = new FileInputStream(path);
        ByteArrayOutputStream byteIn = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int code = 0;
        while ((code = in.read(bytes)) != -1) {
            byteIn.write(bytes, 0 , code);
        }
        return byteIn.toByteArray();
    }
}

package com.java.basic.classloaders;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class LoaderTest {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {

        FileSystemClassLoader loader = new FileSystemClassLoader("D:/new~dir");
        Class Hello = loader.loadClass("com.java.basic.Hello");
        System.out.println(Hello);
        Method main = Hello.getMethod("main", String[].class);
        // 此處需要將其強轉為一個物件. 否則會被認為是多個引數
        main.invoke(Hello.newInstance(),  (Object) new String[]{"a","b"});
    }
}