设为首页 加入收藏

TOP

Java的反射机制(二)
2023-07-25 21:28:03 】 浏览:41
Tags:Java
e String object "Harry Hacker" }

实际上,上面这段代码存在一个问题。由于 name 是一个私有域,所以 get() 方法将会抛出一个 illegalAccessException。只有利用 get() 方法才能得到可访问域的值。除非拥有访问权限,否则 Java 安全机制只允许査看任意对象有哪些域,而不允许读取它们的值。

反射机制的默认行为受限于 Java 的访问控制。然而,如果一个 Java 程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,需要调用 Field、Method 或 Constructor 对象的 setAccessible() 方法。例如:

f.setAtcessible(true); // now OK to call f.get(harry);

setAccessible() 方法是 AccessibleObject 类中的一个方法,AccessibleObject 类是 Field、Method 和 Constructor 类的公共父类。这个特性是为调试、持久存储和相似机制提供的。

调用任意方法

在 C 和 C++ 中,可以从函数指针执行任意函数。从表面上看,Java 没有提供方法指针,即将一个方法的存储地址传给另外一个方法,以便第二个方法能够随后调用它。事实上,Java 的设计者曾说过:方法指针是很危险的,并且常常会带来隐患。他们认为 Java 提供的接口(interface)是一种更好的解决方案。然而,反射机制允许你调用任意方法。

为了能够看到方法指针的工作过程,先回忆一下利用 Field 类的 get() 方法查看数据域值的过程。与之类似,在 Method 类中有一个 invoke() 方法,它允许调用包装在当前 Method 对象中的方法。


可以使用 method 对象实现 C 语言中函数指针(或 C# 中的委派)的所有操作。同 C 一样,这种程序设计风格并不太简便,出错的可能性也比较大。如果在调用方法的时候提供了一个错误的参数,那么 invoke() 方法将会抛出一个异常。

另外, invoke() 方法的参数和返回值必须是 Object 类型的。这就意味着必须进行多次的类型转换。这样做将会使编译器错过检查代码的机会。因此,等到测试阶段才会发现这些错误,找到并改正它们将会更加困难。

在进行类型转换的过程中,编译器无法检查代码中类型转换的正确性,也就是无法保证转换后的类型与原始类型是兼容的。这样就会增加程序出错的可能性,并且如果出现错误的话,调试和修正也会更加困难。

不仅如此,使用反射获得方法指针的代码执行要比直接调用方法明显慢一些。

有鉴于此,建议仅在必要的时候才使用 Method 对象,而最好使用接口以及 Java8 中的 lambda 表达式。

特别要重申:建议 Java 开发者不要使用 Method 对象的回调功能。使用接口进行回调会使得代码的执行速度更快,更易于维护。

参考资料

《Java核心技术卷一:基础知识》(第10版)第 5 章:继承 5.7 反射

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇23基于java教师科研项目管理系统 下一篇springcloud~Sentinel

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目