写点什么

Java 程序经验小结:接口优先于反射机制

发布于: 2021 年 01 月 21 日
Java 程序经验小结:接口优先于反射机制

1、写在开头

给定一个 Class 实例,我们可以获得 Constructor(构造器)、Method(方法)和 Field(域),而这些对象提供了“通过程序来访问类的成员变量、域类型、方法签名等信息”的能力。

通过调用 Constructor、Method、Field 实例上的方法,可以:构造底层类的实例、调用底层类的方法、访问底层类中的域。例如,Method.invoke 使你可以调用任何类的任何对象上的任何方法(遵从常规的安全限制);反射机制甚至能允许一个类使用另一个类,即使当前者被编译时后者还根本不存在(实例化)。

2、反射机制使用的代价

使用反射机制能力,是要付出一些代价的:

  • 丧失了编译时类型检查的好处。(如果程序企图使用反射访问不存在的或者不可访问的方法,运行时便会失败抛出异常,除非我们采取特别的预防措施)

  • 执行反射访问所需要的代码非常笨拙和冗长。(反射代码块的可阅读性是非常低的)

  • 性能损失。(反射方法调用比普通方法调用慢了许多,具体慢了多少,是受到多个因素的影响的,包括虚拟机被分配的内存/堆栈使用情况/当前 CPU 使用情况等等,书作者给了一个大概的说法:速度差异可能小到 2 倍,也可能大到 50 倍)

3、反射应用例子

下面举个例子:创建一个 Set<String> 实例,它的类是由第一个命令行参数指定的,然后将剩余参数插入到集合里面。



public class ReflectClass { public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName(args[0]); } catch (ClassNotFoundException e) { System.err.println("Class not found."); System.exit(1); }
Set<String> s = null; try { s = (Set<String>) c1.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
s.addAll(Arrays.asList(args).subList(1, args.length)); System.out.println(s); }}
复制代码


输出结果:



[1,2,3,45]
复制代码


这个程序像一个“玩偶”,但它演示的这种方法时很强大的:通用的集合测试器,通过侵入式操作一个或多个集合实例,并检查是否遵守 Set 接口的约定

  1. 缺点一:反射的使用可能导致 3 个运行时错误,如果不使用反射方式的实例化,那么这 3 个错误都会成为编译时错误

  2. 缺点二:根据类名生成它的实例,需要 20 行冗长的代码,而调用一个构造器可以非常间接地使用一行代码。一旦对象被实例化,它与其他的 Set 实例就难以区分。

4、总结

反射机制是一种功能强大的机制,对于特定的复杂系统编程任务,它是非常必要的,但也有一些缺点。如果你编写的程序必须要与编译时未知的类一起工作,如有可能,就应该仅仅使用反射机制来实例化对象,而访问对象时则使用编译时已知的某个接口或超类。

5、延伸阅读

《源码系列》

JDK之Object 类

JDK之BigDecimal 类

JDK之String 类

JDK之Lambda表达式


《经典书籍》

Java并发编程实战:第1章 多线程安全性与风险

Java并发编程实战:第2章 影响线程安全性的原子性和加锁机制

Java并发编程实战:第3章 助于线程安全的三剑客:final & volatile & 线程封闭


《服务端技术栈》

《Docker 核心设计理念

《Kafka史上最强原理总结》

《HTTP的前世今生》


《算法系列》

读懂排序算法(一):冒泡&直接插入&选择比较

《读懂排序算法(二):希尔排序算法》

《读懂排序算法(三):堆排序算法》

《读懂排序算法(四):归并算法》

《读懂排序算法(五):快速排序算法》

读懂排序算法(六):二分查找算法》


《设计模式》

设计模式之六大设计原则

设计模式之创建型(1):单例模式

设计模式之创建型(2):工厂方法模式

设计模式之创建型(3):原型模式

设计模式之创建型(4):建造者模式


发布于: 2021 年 01 月 21 日阅读数: 23
用户头像

Diligence is the mother of success. 2018.03.28 加入

公众号:后台技术汇 笔者主要从事Java后台开发,喜欢技术交流与分享,保持饥渴,一起进步!

评论

发布
暂无评论
Java 程序经验小结:接口优先于反射机制