1700447824
1700447825
Reflection.ensureMemberAccess(……);
1700447826
1700447827
……
1700447828
1700447829
}
1700447830
1700447831
}
1700447832
1700447833
//直接执行方法
1700447834
1700447835
return methodAccessor.invoke(obj, args);
1700447836
1700447837
}
1700447838
1700447839
看了这段代码,诸位就很清楚了:Accessible属性只是用来判断是否需要进行安全检查的,如果不需要则直接执行,这就可以大幅度地提升系统性能(当然了,由于取消了安全检查,也可以运行private方法、访问private私有属性了)。经过测试,在大量的反射情况下,设置Accessible为true可以提升性能20倍以上。
1700447840
1700447841
AccessibleObject的其他两个子类Field和Constructor与Method的情形相似:Accessible属性决定Field和Constructor是否受访问控制检查。我们在设置Field或执行Constructor时,务必要设置Accessible为true,这并不仅仅是因为操作习惯的问题,还是在为我们系统的性能考虑。
1700447842
1700447843
注意 对于我们已经“习惯”了的代码,多思考一下为什么。
1700447844
1700447845
1700447846
1700447847
1700447849
编写高质量代码:改善Java程序的151个建议 建议104:使用forName动态加载类文件
1700447850
1700447851
动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,对Java程序来说,一般情况下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否要加载一个类,比如从Web上接收一个String参数作为类名,然后在JVM中加载并初始化,这就是动态加载,此动态加载通常是通过Class.forName(String)实现的,只是这个forName方法到底是什么意思呢?
1700447852
1700447853
我们知道一个类文件只有在被加载到内存中后才可能生成实例对象,也就是说一个对象的生成必然会经过以下两个步骤:
1700447854
1700447855
加载到内存中生成Class的实例对象。
1700447856
1700447857
通过new关键字生成实例对象。
1700447858
1700447859
如果我们使用的是import关键字产生的依赖包,JVM在启动时会自动加载所有依赖包下的类文件,这没有什么问题,如果要动态加载类文件,就要使用forName方法了,但问题是我们为什么要使用forName方法动态加载一个类文件呢?那是因为我们不知道生成的实例对象是什么类型(如果知道就不用动态加载),而且方法和属性都不可访问呀。问题又来了:动态加载的意义在什么地方呢?
1700447860
1700447861
意义在于:加载一个类即表示要初始化该类的static变量,特别是static代码块,在这里我们可以做大量的工作,比如注册自己,初始化环境等,这才是我们要重点关注的逻辑,例如如下代码:
1700447862
1700447863
class Utils{
1700447864
1700447865
//静态代码块
1700447866
1700447867
static{
1700447868
1700447869
System.out.println(“Do Something”);
1700447870
1700447871
}
1700447872
1700447873
}
[
上一页 ]
[ :1.700447824e+09 ]
[
下一页 ]