动态加载预编译的 class 而无需反射
Dynamically Loading a pre-compiled class without reflection
在我的具体情况下,我想在运行时加载一个 class,其中: 我在编译时有 class(及其定义),但我只找到 location 在运行时包含它的 jar。与 classic class 加载情况有些相反,其中 class 的 name 仅在运行时已知。
让我们假设要加载的 class 是 org/animals/Cat.class 并且它是许多中的一个 class animals.jar。当我编译我的程序时,animals.jar 在我的编译时 class 路径中,因为我知道它在哪里,例如:
javac -cp <path to>/animals.jar Something.java
我可以导入它,引用它,然后编译我的程序Something.java
import org.animals.Cat;
...
Cat c = new Cat();
c.makesound();
现在我将程序部署到生产系统,其中 animals.jar 和其他库的位置仅在运行时才知道。如果我知道位置,我可以使用
java -cp <path to>/animals.jar Something
但我只是在运行时才发现它。我希望我可以使用 URLClassLoader 来使其工作。假设传入的 jar 运行时路径存储在 'location' 下,我可以创建一个 classloader 来加载它:
URL url = new File(location + "/animals.jar").toURI().toURL();
URL[] urls = new URL[]{url};
URLClassLoader cLoader = new URLClassLoader(urls);
然后只需在我的程序中使用 Cat 编译后的代码,而不必求助于
进行反思。例如,这是我要避免的:
Class clazz = cLoader.loadClass("org.animals.Cat")
Object o = clazz.newInstance();
Method m = o.getClass().getMethod("makesound", ...);
这真的可以不用反思吗?我可以在编译时利用知道 class 的好处吗?或者我必须像上面那样使用反射。
谢谢。
如果您的 Cat
class 已知会实现某些 Animal
接口,那么您可以执行 Animal a = (Animal)o
并开始调用 Animal
方法a
没有使用反射。
在我的具体情况下,我想在运行时加载一个 class,其中: 我在编译时有 class(及其定义),但我只找到 location 在运行时包含它的 jar。与 classic class 加载情况有些相反,其中 class 的 name 仅在运行时已知。
让我们假设要加载的 class 是 org/animals/Cat.class 并且它是许多中的一个 class animals.jar。当我编译我的程序时,animals.jar 在我的编译时 class 路径中,因为我知道它在哪里,例如:
javac -cp <path to>/animals.jar Something.java
我可以导入它,引用它,然后编译我的程序Something.java
import org.animals.Cat;
...
Cat c = new Cat();
c.makesound();
现在我将程序部署到生产系统,其中 animals.jar 和其他库的位置仅在运行时才知道。如果我知道位置,我可以使用
java -cp <path to>/animals.jar Something
但我只是在运行时才发现它。我希望我可以使用 URLClassLoader 来使其工作。假设传入的 jar 运行时路径存储在 'location' 下,我可以创建一个 classloader 来加载它:
URL url = new File(location + "/animals.jar").toURI().toURL();
URL[] urls = new URL[]{url};
URLClassLoader cLoader = new URLClassLoader(urls);
然后只需在我的程序中使用 Cat 编译后的代码,而不必求助于 进行反思。例如,这是我要避免的:
Class clazz = cLoader.loadClass("org.animals.Cat")
Object o = clazz.newInstance();
Method m = o.getClass().getMethod("makesound", ...);
这真的可以不用反思吗?我可以在编译时利用知道 class 的好处吗?或者我必须像上面那样使用反射。
谢谢。
如果您的 Cat
class 已知会实现某些 Animal
接口,那么您可以执行 Animal a = (Animal)o
并开始调用 Animal
方法a
没有使用反射。