简单java反射,小例子,仅供参考

本文通过一个具体的Java代码示例展示了如何使用反射来获取类并调用其方法。示例中定义了一个简单的类c,包含一个返回字符串的方法cc,并通过反射机制调用了该方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package test;
public class c {

public String cc(String name,String addr){
	return "My name is "+name+",I'm working in "+addr;
}
}


Class cl=Class.forName("test.c");
	   Method m= cl.getMethod("cc",String.class,String.class);
	   Object o=m.invoke(cl.newInstance(), "lcd","bj");
	   System.out.println(o);


### Java 17 反射首次使用报错的原因分析 在 Java 17 中,反射机制的行为可能受到模块化系统的限制。自 Java 9 起引入的 **JPMS (Java Platform Module System)** 对类加载器和包可见性进行了更严格的控制。如果目标类所在的模块未显式声明 `opens` 或者 `exports` 到请求方模块,则可能会引发访问权限错误[^3]。 常见的错误消息类似于以下内容: ``` java.lang.IllegalAccessException: class com.example.MyClass cannot access a member of class java.base/java.util.ArrayList with modifiers "private" ``` 这种问题通常发生在尝试通过反射访问私有成员变量或方法时。即使这些成员被标记为可访问 (`setAccessible(true)`),也可能因模块化的安全策略而失败。 --- ### 解决方案 #### 方法一:修改模块描述符文件 如果可以更改代码中的模块定义,在模块信息文件(`module-info.java`)中添加适当的 `opens` 声明: ```java // module-info.java module your.module.name { opens com.example.package.to.reflect; // 打开特定包供其他模块反射访问 } ``` 此操作允许指定包对外部模块开放反射功能,从而避免非法访问异常[^4]。 #### 方法二:运行时参数配置 如果不具备修改源码的能力,可以通过 JVM 启动选项授予必要的权限。例如: ```bash --add-opens java.base/java.util=ALL-UNNAMED ``` 上述命令表示向所有未命名模块打开 `java.base/java.util` 包以支持反射访问。对于具体的应用场景,可以根据实际需求调整路径和范围。 #### 方法三:动态设置 AccessibleObject 的权限 尽管不推荐作为长期解决方案,但在某些情况下可以直接强制设置字段或方法的可访问状态: ```java Field field = SomeClass.class.getDeclaredField("fieldName"); field.setAccessible(true); // 强制开启访问权限 ``` 需要注意的是,这种方法仍然受模块化规则约束,因此仅适用于已正确配置的环境[^5]。 --- ### 示例代码展示 以下是综合运用以上技术的一个简单例子: ```java import java.lang.reflect.Field; public class ReflectionExample { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("java.util.ArrayList"); Field sizeField; try { sizeField = clazz.getDeclaredField("size"); // 尝试获取 ArrayList 类内部的 'size' 字段 } catch (NoSuchFieldException e) { throw new RuntimeException("Failed to locate target field", e); } boolean wasAccessible = sizeField.isAccessible(); if (!wasAccessible) { sizeField.setAccessible(true); // 如果不可达则临时解锁 } Object instance = clazz.getConstructor().newInstance(); // 创建实例对象 int defaultValue = (int) sizeField.getInt(instance); System.out.println("Default Size Value: " + defaultValue); if (!wasAccessible && !clazz.getName().startsWith("java.")) { sizeField.setAccessible(false); // 还原原始状态以防安全隐患 } } } ``` 注意该程序片段假设能够成功定位到所需组件并拥有足够的执行特权[^6]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简单就好-怒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值