介绍
这篇文章主要介绍了JVM反射原理是什么,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。
反射定义
1, JAVA反射机制是在<强>运行状态中强>
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为JAVA语言的反射机制。
反射提供的功能:
- <李>在运行时判断任意一个对象所属的类李> <>李在运行时构造任意一个类的对象李> <>李在运行时判断任意一个类所具有的成员变量和方法李> <李>在运行时调用任意一个对象的方法李>
<强>(如果属性是私人的,正常情况下是不允许外界操作属性值,这里可以用领域类的种setAccessible(真正的)方法,暂时打开操作的权限)强>
反射的使用场景
- <李> JAVA编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射李> <>李如果编码时不知道类或者对象的具体信息,此时应该使用反射来实现李>
反射源码解析
举例API:
forname (“com.my.reflectTest") .newInstance()复制代码
1。反射获取类实例forname (“xxx");
首先调用了. lang。类的静态方法,获取类信息!
注意:forName()反射获取类信息,并没有将实现留给了java,而是交给了jvm去加载!
主要是先获取类加载器,然后调用本机方法,获取信息,加载类则是回调入参类加载器进类加载!
@CallerSensitive 公共静态Class<?比;forName(字符串名称) 抛出ClassNotFoundException {//先通过反射,获取调用进来的类信息,从而获取当前的类加载器 Class<?比;调用者=Reflection.getCallerClass ();//调用本机方法进行获取类信息 返回forName0(类名,真的,ClassLoader.getClassLoader(调用者),调用者); }复制代码
2。java.lang.ClassLoader——loadclass ()
//java.lang.ClassLoader 保护Class<?比;loadClass(字符串名称,布尔解决) 抛出ClassNotFoundException {//先获取锁 同步(getClassLoadingLock(名字)){//首先,检查是否已经加载的类//如果已经加载了的话,就不用再加载了 Class<?比;c=findLoadedClass(名称); 如果(c==null) { 长t0=system . nanotime (); 尝试{//双亲委托加载 如果(父!=null) { c=父母。loadClass(名称、假); 其他}{ c=findBootstrapClassOrNull(名称); } }捕捉(ClassNotFoundException e) {//如果类没有找到抛出ClassNotFoundException//非空的父类加载器 }//父类没有加载到时,再自己加载 如果(c==null) {//如果仍然没有找到,然后调用findClass//找到该类。 长t1=system . nanotime (); c=findClass(名称);//这是定义类装入器;记录数据 sun.misc.PerfCounter.getParentDelegationTime ()。addTime (t1 - t0); sun.misc.PerfCounter.getFindClassTime () .addElapsedTimeFrom (t1); .increment sun.misc.PerfCounter.getFindClasses () (); } } 如果(解决){ resolveClass (c); } 返回c; } } 保护对象getClassLoadingLock(字符串名称){ 对象锁=; 如果(parallelLockMap !=null) {//使用ConcurrentHashMap来保存锁 对象newLock=新对象(); 锁=parallelLockMap。putIfAbsent(类名,newLock); 如果(锁==null) { 锁=newLock; } } 返回锁; } 保护最终Class<?比;findLoadedClass(字符串名称){ 如果(! checkName(名称)) 返回null; 返回findLoadedClass0(名称); }复制代码
3。newInstance ()
newInstance()其实相当于调用类的无参构造函数,主要做了三件事复制代码
- <李>
权限检测,如果不通过直接抛出异常;
李> <李>查找无参构造器,并将其缓存起来。
李> <李>调用具体方法的无参构造方法,生成实例并返回;
李>//首先肯定是Class.newInstance @CallerSensitive 公共T newInstance () 抛出InstantiationException, IllegalAccessException { 如果(System.getSecurityManager () !=null) { checkMemberAccess(成员。公众Reflection.getCallerClass(),假); }//注意:以下代码可能不是严格纠正下//当前Java内存模型。//构造函数查找//newInstance()其实相当于调用类的无参构造函数,所以,首先要找到其无参构造器 如果(cachedConstructor==null) { 如果(这==Class.class) {//不允许调用类的newInstance()方法 把新的IllegalAccessException ( “不能叫newInstance()>私人ConstructorJVM反射原理是什么