Java反射库 - 使用没有包信息的Class.forName()

时间:2012-06-20 20:38:29

标签: java class reflection dynamic

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

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”作为回报。所以我不明白为什么Reflection库与使用'java'调用JVM的工作方式不同,如果没有提供包名,它只是在同一目录中查找。当我的类没有关联的包名称时,我不确定如何将此库与用户定义的类一起使用。

5 个答案:

答案 0 :(得分:3)

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

类路径中是否有Node.class?您可以通过将当前目录添加到类路径来实现此目的。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

使用上面的ReflectionTest.java和以下Node.java

,它对我有用
public class Node { }

您是否编译了Node.java以及ReflectionTest.java?由于ReflectionTest类对Node类没有编译时依赖性,因此javac在编译Node.class时不会自动编译ReflectionTest.class

答案 4 :(得分:1)

Java中没有类的目录概念。类位于包中,或位于缺省包中,并从必须位于类路径中的目录或jar中加载。

如果包含Node.class的目录在类路径中,则上述代码应该有效。

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