簡體   English   中英

Java動態加載類問題

[英]Java dynamic loading a class issue

我正在嘗試編寫一個代碼,該代碼在從字符串創建它之后會編譯並運行另一個Java類。

我的問題是我跑步時

    Class classToLoad = null;
    ClassLoader classLoader = Server.class.getClassLoader();
    try {
        classToLoad = classLoader.loadClass(className);
    } catch (Exception e) {
        e.printStackTrace();
    }

它將引發ClassNotFoundException。 我的問題與軟件包無關,因為如果我調試代碼並將斷點放在“ getClassLoader”之前,然后重新加載類,則我的代碼運行良好,並且可以看到該應用程序中最近創建的類。

如何在運行時重新加載類,以便loadClass可以工作?

看一下本教程

ClassLoader加載/重新加載示例

...讓我們看一個簡單的例子。 下面是一個簡單的ClassLoader子類的示例。 請注意,它如何將類加載委派給其父級,但打算重新加載的是一個類。 如果此類的加載委托給父類加載器,則以后無法重新加載。 請記住,一個類只能由相同的ClassLoader實例加載一次。

如前所述,這只是一個示例,用於向您展示ClassLoader行為的基礎。 它不是您自己的類加載器的生產就緒模板。 您自己的類加載器可能不應僅限於單個類,而應該知道您需要重新加載的類的集合。 另外,您可能也不應該對類路徑進行硬編碼。

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }

    public Class loadClass(String name) throws ClassNotFoundException {
        if(!"reflection.MyObject".equals(name))
                return super.loadClass(name);

        try {
            String url = "file:C:/data/projects/tutorials/web/WEB-INF/" +
                            "classes/reflection/MyObject.class";
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            InputStream input = connection.getInputStream();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int data = input.read();

            while(data != -1){
                buffer.write(data);
                data = input.read();
            }

            input.close();

            byte[] classData = buffer.toByteArray();

            return defineClass("reflection.MyObject",
                    classData, 0, classData.length);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}

下面是MyClassLoader的示例用法。

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

    ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
    MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
    Class myObjectClass = classLoader.loadClass("reflection.MyObject");

    AnInterface2       object1 =
            (AnInterface2) myObjectClass.newInstance();

    MyObjectSuperClass object2 =
            (MyObjectSuperClass) myObjectClass.newInstance();

    //create new class loader so classes can be reloaded.
    classLoader = new MyClassLoader(parentClassLoader);
    myObjectClass = classLoader.loadClass("reflection.MyObject");

    object1 = (AnInterface2)       myObjectClass.newInstance();
    object2 = (MyObjectSuperClass) myObjectClass.newInstance();

}

可能會問:“您正在加載類的上下文是什么?” 將有助於更好地回答您的問題。

像Spring這樣的大多數標准框架都在內部處理加載類,並僅公開那些類提供的方法。

嘗試使用Class.forName(String name)嘗試加載類並將句柄返回給類對象。

如果要專門使用自己的類加載器加載類,請使用重載的類: Class.forName(字符串名稱,布爾值初始化,ClassLoader加載器)

但是您將需要確保您的類加載器能夠找到要正確加載的類。

對於您正在使用的類加載器,請嘗試: Thread.currentThread()。getContextClassLoader()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM