Hi 大家好,我是 DHL。大众号:ByteCode ,专注共享风趣硬核原创内容,Kotlin、Jetpack、功用优化、体系源码、算法及数据结构、动画、大厂面经
在之前的文章和视频中咱们拆分了不同的场景对比反射的功用。
- 文字版: 侧重于细节上的知识点更多、更加具体,揭秘反射真的很耗时泛型通配符吗,射 10 万次耗时多久
- 视频版: 经过动画展示讲解,更加的清楚、直观,视频版别 b算法的空间复杂度是指ilibili 地址: b23.tv/Hprua24
在之前的文章中提到了一个提高功用java培训十分重要的点,将 Accessible
设置 true
反射泛型通配符速度会进一步提高,假如单看一个程序,或许这点功用微不足道,可是假java是什么意思如放在一个大的复杂的工程下面,运行在许多的低端机下,一行代码提高的功用,或许比你写 100 行代码提高的功用更加java环境变量配置明显。
而今日这篇文章从源码的角度页面性能优化剖析一下 isAccessible()
办法的作用,为什么将 Accessible
设置为 true
能够提高功用,算法在开端剖析之前,咱们先写一段代码。
- 声明一个普通类,里面有个
public
办法gejava语言tName()
和priva算法te
办法getAddress()
class Person {
public fun getName(): String {
return "I am DHL"
}
private fun getAddress(): String {
return "BJ"
}
}
- 经过反射获取
getName()
和getAddress()
办法,花 3 秒钟考虑一下,下面的代码输出的成果
// public 办法
val method1 = Person::class.declaredFunctions.find { it.name == "getName" }
println("access = ${method1?.isAccessible}")
// private 办法
val method2 = Person::class.declaredFunctions.find { it.name == "getAddress" }
println("access = ${method2?.isAccessible}")
无论是调javaee用 public getNam页面性能优化e()算法的有穷性是指
办法仍是调用 priv泛型编程ate getAddress()
办法,最终输出的成果都为 false
,动画片少儿小猪佩奇经过这个例子也间接说明晰 isAccessible()
办法并不是用来表明拜访权限的。
当咱们经过反射调用 private
办法时,都需求履行 setAccessible()
办法设置为动画片熊出没 true
, 否者会抛出下面的异常。
java.lang.IllegalAccessException: can not access a member of class com.hi.dhl.demo.reflect.Person
假如经过反射调用 public
办法,不设置 Accessible
为 true
,也能够正常调用,所以有许多小伙伴以为 isAcce算法导论ssible()
办法用来表明拜访权限,其实这种理解是过错的。
咱们一同来看一下源码是怎么解释的,办法 isAccessible()
坐落 AccessibleObject
类中。
public class AccessibleObject implements AnnotatedElement {
......
// NOTE: for security purposes, this field must not be visible
boolean override;
public boolean isAccessible() {
return override;
}
public void setAccessible(boolean flag) throws SecurityException {
......
}
......
}
Accessi动画片小猪佩奇bleObject
是 Field
、 Method
、 Constructor
的父类,调用 isAccessible()
回来 override
的值,java是什么意思而字段泛型是什么 overridejava语言
首要判算法的特征断是否要进行安全检查。
字段 override
在 AccessibleObject
子类傍边运java环境变量配置用,所算法的特征以咱们一同来看一下它的子类 Method
。
public Object invoke(Object obj, Object... args){
// 是否要进行安全检查
if (!override) {
// 进行快速验证是否是 Public 办法
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
// 回来调用这个办法的 Class
Class<?> caller = Reflection.getCallerClass();
// 做权限拜访的校验,缓存调用这个办法的 Class,防止下次在做检查
checkAccess(caller, clazz, obj, modifiers);
}
}
......
return ma.invoke(obj, args);
}
字段 override
供给给子类去重写,算法它的值决议了是否要进行安全检查,假如要进行安全检查,则会履行 quickCheckMemberAcc动画电影ess()
快速验证是否是 Public
办法,防止调用 getCallerClass()
。
- 假如是
Public
办法,防止做安全检查,所以咱们在代泛型通配符码中不调用setAccessible(true)
办法,也不会抛出异常 - 假如不是
Public
办法则会调用getCallerClass()
获取调用这动画片猫和老鼠个办法的 Class,履行checkAccess()
办法进算法的时间复杂度取决于行安全检查。
// it is necessary to perform somewhat expensive security checks.
// A more complicated security check cache is needed for Method and Field
// The cache can be either null (empty cache)
volatile Object securityCheckCache; // 缓存调用这个办法的 Class
void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers){
......
Object cache = securityCheckCache; // read volatile
if(cache == 调用这个办法的 Class){
return; // ACCESS IS OK
}
slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
......
}
void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,Class<?> targetClass){
Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
Object cache = 调用这个办法的 Class
securityCheckCache = cache; // 缓存调用这个办法的 Class
}
源码中动画片猫和老鼠注释也说明晰,假如要进行安全检查那么它的代价是十分贵重的,所以用变量 securityCheckCache
缓存调用这个办法的 Class。假如下次运用相同的 Class,就不需求在做安全检查,可java模拟器是动画这个缓存有动画电影个缺陷,假如换一个调用这个办法的 Class,需求再次做安全检查,并js性能优化且会覆盖之前的缓存成果。
假如要在运行时修改特点或许调用某个办法时,都要进行动画片少儿小猪佩奇安全检查,而安全检查是十分动画制作软件消耗资源js性能优化的,所以 JDK 供给了一个 setAcce前端性能优化ssible()
办法,能够绕过安全检查,让开发者自己来决议是否要避开安全检查。
因为反射本身是十分慢的,假如能够防止安全检查,能够进一步提高功用,在之前的文章 揭秘反射真的很耗时吗,射 10 万次耗时多久,针对泛型的作用不同场景,别离测验了反射前后以及封闭安全检查的耗时。
正常调用 | 反射 | 反射优化后 | 反射优化后泛型list和普通list有什么区别关掉安全检查 | |
---|---|---|---|---|
创立目标 | 0.578 ms/op | 4.710 ms/op | 1.018 ms/op | 0.943 ms/op |
办法调用 | 0.422 ms/op | 10.533 ms/op | 0.844 ms/op | 0.687 ms/op |
特点调用 | 0.241 ms/op | 12.432 ms/op | 1.362 ms/op | 1.202 ms/op |
伴生目标 | 0.470 ms/op | 5.661 ms/op | 0.840 ms/op | 0.702 ms/op |
从测验成果能够看出来,履行 setAccessible()
办法,设置为 true
关掉安全检查之后,反射速度得到了进一步的提高,更接近于正常调用。
我正在参与技术算法社区创作者签约方案招募活动,点击链接报名投稿。
全文到这里就完毕了,感谢你的阅览,坚持原创不易,欢迎在看、点赞、共享动画片汪汪队给身边的小伙伴,我会动画大放映继续共享原创干货!!!
真诚推荐你重视我,大众号:ByteCode ,继续共享硬核原创内容,Kotl动画电影in、Jetpac动画电影k、功用优化、体系源码、算法及数据结构、动画、大厂面经。
近期必读热门文章
- 90%人不明白泛型list和普通list有什么区别的泛型局限性,泛型擦除,星投影
- 90%的人都不知道的知识点,Kotlin 和 Java 的协变和逆变
- CPUjava编译器 怎么记录函数调用进程和回来进程
- 揭秘反射真的很耗时吗,射 10 万次耗时多久泛型list和普通list有什么区别
- 你知道 Iterable 有多慢吗?试试算法的时间复杂度取决于它提高功用
- 揭秘 Kotlin 1.6.20 重磅功用 Context算法是指什么 Receivers
- Stack Overflow 上最热门的 10 个 Kotlin 问题
- Andr算法导论oid 12 已来泛型方法,你的 App 溃散了吗?
- Googl页面性能优化e 宣告废弃 LiveData.observe 办法
- 影响功用的 Kotlin 代码(一)
- 揭秘 Kotlin 中的 == 和 ==算法工程师=
最终推荐长时刻更新和保护的项目
-
个人博客,将一切文章进行分类,欢迎前去检查 hi-dhl.com
-
KtKit 小巧而实用,用 Kotlin 语言编写的工具库,性能优化的方法欢迎前去检查 KtKit
-
方案树立一个最全、最新的 AndroidX Jetpack 相关组件的实战项目以及相关组件原理剖析文章,正在逐步增加 Jetpa前端性能优化ck 新成员,库房继续更新,欢迎前去检查 AndroidX-Jetpack-Practic算法分析的目的是e
-
L算法的五个特性eetCode / 剑指 offer / 国内外大厂面试题 / 多线程题解,语言 Java 和 kotlin,页面性能优化包含多种解法、解题思路、时刻复杂度、空间复杂度剖析
- 剑指 offer 及国内外大厂面试题解:在线阅览
- LeetCode 系列题解:在线阅览泛型方法的定义和使用