gpt4 book ai didi

java - 在 Java9 中,如果我不知道它是模块,我如何反射性地加载一个类?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:08:22 28 4
gpt4 key购买 nike

假设我有一个给定众所周知的包名和类的应用程序,我需要反射性地加载该类并从中调用一些方法。假设这个类在另一个 java jar(“库”)中可用。

到目前为止,在java 9之前,由于类路径中的所有类都可用,所以实现起来很简单。

但是,对于 Java 9,如果应用程序“模块”不需要“库”包,则库类不可访问。

如何使用模块化 jar 实现相同的行为?

例子:

这是我的申请:

// This is defined in ReflectionApp.jar
// ReflectionApp
// └── src
// ├── module-info.java
// └── org
// └── reflection
// └── app
// └── ReflectionApp.java
//
package org.reflection.app;

import java.lang.reflect.Method;

public class ReflectionApp {
private static final String PACKAGE = "org.reflection.lib";
private static final String CLASS = "ReflectiveClass";
private static final String METHOD = "doSomeWork";

public static void main(String[] args) throws Exception {

// This will not work using java9
Class<?> klass = Class.forName(String.format("%s.%s", PACKAGE, CLASS));
Object obj = klass.getDeclaredConstructor().newInstance();
Method meth = klass.getDeclaredMethod(METHOD);
meth.invoke(obj);
}
}

这是我的图书馆

// This is defined in ReflectionLib.jar
// ReflectionLib
// └── src
// ├── module-info.java
// └── org
// └── reflection
// └── lib
// └── ReflectiveClass.java
//
package org.reflection.lib;

public class ReflectiveClass {

public void doSomeWork() {
System.out.println("::: Doing some work!");
}
}

目前,如果我尝试这样调用它(假设所有 jar 都已创建并在 lib 目录中可用):

java --module-path lib -m ReflectionApp/org.reflection.app.ReflectionApp

然后我得到一个 Exception in thread "main"java.lang.ClassNotFoundException: org.reflection.lib.ReflectiveClass

--- 解决方案 ---

感谢@Nicolai,我能够通过向命令添加 --add-modules 参数使其运行。

⇒  java --module-path lib --add-modules ReflectionLib -m ReflectionApp/org.reflection.app.ReflectionApp
::: Doing some work!

最佳答案

plenty of ways to make reflection work但是它们都不像模块系统之前的“它只是工作”的方式那样直接。让我针对您的特定问题缩小范围。

但在此之前,您必须确保 模块确实进入了模块图中。如果初始模块不需要传递它,则可以使用 --add-modules library 将其添加到图中。

包导出

您写道“如果应用程序‘模块’不需要‘库’包,则库类不可访问”。假设您指的是 module 而不是 package 这是正确的但不适用于此处。辅助功能基于两件事:

  1. 两个模块之间的读取边
  2. 导出访问类型的访问模块

你没有写关于 2 的任何内容。但是如果 module library { exports org.reflection.lib; },那么你就可以随意使用反射了。原因是当您开始使用反射 API 时会自动添加读取边缘。

不可访问的类型

现在它变得更有趣了。如果 library 模块不导出 org.reflection.lib 或者如果 ReflectiveClass 不是公共(public)的,则上述方法不起作用。在这种情况下,您有很多选择:

  • 公开类型并导出包(可能只导出到访问模块)
  • 打开包(可能只对访问模块)或模块
  • 添加命令行选项以实现上述任何一个

要了解它们的比较情况,请查看这篇关于 reflection vs encapsulation in Java 9 的文章.

关于java - 在 Java9 中,如果我不知道它是模块,我如何反射性地加载一个类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43246535/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com