4

我有一个项目需要在运行时动态创建类,其中唯一可用的信息是字符串形式的类名称。我现在正在使用一些简单的反射库方法进行测试,但我的问题是,如果我试图“动态”加载的类位于同一目录中,为什么我必须提供完全限定的类名称?我使用的是linux,没有开发环境,只是我试图在同一个目录中调用的所有类,没有任何包声明。我必须设置一个包系统才能使用反射吗?这是这个小代码片段......

public class ReflectionTest {
    public static void main(String[] args) {
        try {
            Class nodeClass = Class.forName("Node");
            System.out.println(nodeClass.toString());
        } catch (ClassNotFoundException cnfe) {
            System.out.println("Error");
        }
    }
}

现在,这会引发错误。但是当我创建一个 Node 实例,然后使用 获得它的完全限定类名时Node.getClass().getName(),我只会得到“Node”作为回报。所以我不明白为什么反射库与使用“java”调用 JVM 的工作方式不同,如果没有提供包名,它只会在同一个目录中查找。当我的类都没有关联的包名称时,我不确定如何将此库与用户定义的类一起使用。

4

5 回答 5

2

您的代码应该按照描述工作。也就是说,如果你可以打电话,new Node()你也应该可以打电话Class.forName("Node")。我刚刚尝试使用无包类进行验证,一切都按预期工作。

Node.class在类路径中可用吗?您可以通过将当前目录添加到类路径来使其工作。

于 2012-06-20T20:46:22.503 回答
1

包名是java命名系统的一个组成部分。但是,如果您的类没有声明包,它位于根包中,您发布的代码应该可以工作。

我的猜测:该目录实际上不在 CLASSPATH 中。尝试添加当前目录 (./) 并确保它实际上是当前目录,或者在 CLASSPATH 中明确包含目录(绝对路径)。请参阅文档以了解如何设置 CLASSPATH(环境、jvm 选项、运行时是您的选项)

于 2012-06-20T20:47:51.473 回答
0

Java 中没有类目录的概念。类在包中,或者在默认包中,并且从必须在类路径中的目录或 jar 中加载。

如果包含的目录Node.class在类路径中,则上面的代码应该可以工作。

但是使用默认包是一个非常非常糟糕的做法。每个类都应该在一个包中。

于 2012-06-20T20:46:53.110 回答
0

首先,您需要确保您尝试加载的类位于类路径中,因此在启动 jvm 时尝试将当前文件夹添加到其中:java -cp . ReflectionTest

包的概念是让你的东西井井有条并且能够重用名称。提供完全限定的名称,确保您使用的是正确的 Node 类,例如不使用org.w3c.dom.Node或类似的东西,它会隐式地随 java.util 提供。

于 2012-06-20T20:46:11.413 回答
0

它适用于我使用ReflectionTest.java上面的确切内容和以下内容Node.java

public class Node { }

你编译Node.java好了ReflectionTest.java吗?由于类对ReflectionTest类没有编译时依赖,javac 在编译时Node不会自动编译。Node.classReflectionTest.class

于 2012-06-20T20:46:13.500 回答