【问题标题】:Classloader and loading a class whose location does not equal its package类加载器并加载一个位置不等于其包的类
【发布时间】:2013-12-03 08:19:22
【问题描述】:

每当编译的.class 文件出现在该特定目录中时,我希望能够从已知目录加载一个类。但是,无论package 声明在其.java 文件中是什么,我都希望加载.class。例如,我想加载这个类:

package com.javaloading.test;

public class SomeClassInPackage {
    private String name = "The name of this Class is SomeClass.";
    public String getName(){
            return name;
    }

}

它在包com.javaloading.test 中。然后我想使用这个类来加载它:

public class GetPackage {

    public static void main(String[] args){
            new GetPackage().loadMyClass();
    }

    public void loadMyClass(){
            // Get the current class loader
            ClassLoader cl = getClass().getClassLoader();
            try {
                    Object o = cl.loadClass("SomeClassInPackage");
                    System.out.println("Class loaded!");
            } catch (ClassNotFoundException ex){
                    System.out.println("Could not load class");
            }
    }
}

如果我把上面两个类的.class文件放到同一个目录下运行GetPackage会报错

线程“主”java.lang.NoClassDefFoundError 中的异常: SomeClassInPackage(错误名称: com/javaloading/test/SomeClassInPackage

我需要能够(从文件中)加载一个类,而不管它是声明的包,也不必真正知道它的包。然后我会检查加载的类的包信息。这是否可以使用系统类加载器或自定义类加载器,或者在不了解包结构的情况下是不可能的?如果可能的话,任何建议表示赞赏。

【问题讨论】:

    标签: java classloader dynamic-class-loaders


    【解决方案1】:

    如果没有相应的包结构就无法加载类,这意味着如果要加载类,则必须将其放置在与其包名称对应的文件夹中,或者该类在 jar 文件中但在同一个文件中文件夹结构。

    但是假设您要加载外部类,这意味着不在执行该程序的类路径中,并且您希望在执行期间将其加载到当前类加载器中。请参阅此链接How to load the classes at runtime。这也将为您的下一个问题提供答案,您希望加载程序根据其名称或包选择的类。

    【讨论】:

    • 如果不是从文件目录加载一个类(并且该类有一个未知的包)我想从一个网络套接字加载该类,那会以与上述类似的方式失败吗?跨度>
    • 我确实想知道由于本文中指出的安全隐患,是否会阻止执行我上面要求的操作:drdobbs.com/jvm/a-java-2-network-class-loader/184404484
    • 我不认为 N​​oClassDefFoundError 是由于安全问题。当您使用 cl.loadClass("SomeClassInPackage")。它尝试在默认包中查找该类,并假定该 .class 存在于类路径的根文件夹中并且没有找到它。但是假设您的 GetPackage 在默认包中,并且您将 com.javaloading.test.SomeClassInPackage 的 .class 文件放在 GetPackage 类所在的根文件夹中,那么即使在这种情况下 SomeClassInPackage 也不符合加载条件,因为它不在正确的位置。
    • 如果你真的想从任意位置加载类,那么你可以使用 java 序列化。但这与类加载不同,因为您正在加载一个类及其状态,而不是像 Java 中的“new”关键字那样加载 .class。
    猜你喜欢
    • 1970-01-01
    • 2013-12-17
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多