我有一个项目需要在运行时动态创建类,其中唯一可用的信息是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的工作方式不同,如果没有提供包名,它只是在同一目录中查找。当我的类没有关联的包名称时,我不确定如何将此库与用户定义的类一起使用。
答案 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
的目录在类路径中,则上述代码应该有效。
但使用默认包是非常糟糕的做法。每个班级都应该在一个包中。