首先来说说反射机制的概念:
程序在运行时,
对于类来说,可以知道该类的任意属性和方法;
对于对象来说,可以调用该对象的任意方法和属性;

就以上这种动态获取信息的机制就称为Java的反射机制
彻底了解反射之前,我们还需要知道一个知识点:一般情况下,Java类在编译前,该类的相关数据就已经被加载到JVM中,而我们的反射机制可以在程序运行时,去操作类的方法,属性等,这种操作就很动态。

简单了解之后,相信有点理解,但是还是不能完全理解,那就通过下面这个说明,通过将这个概念和我们所熟悉的概念进行比较,可以让我们容易理解:
在Java编译中,主要有两种编译方式 :
静态编译:例如在我们编写程序,使用new关键字创造对象,在编译的时候,就会确定对象类型和所绑定的对象
动态编译:所谓动态编译,就是在运行时,才进行编译,使用的是newInstance()这个方法,稍后会讲解.

优点:
这样体现了Java的灵活性,多态特性同时也降低了类之间的耦合,spring容器中的类,就是这样执行的,降低了模块之间的耦合。
缺点:
因为该反射机制,是在jvm中执行,所以其相当于比静态编译多了这些步骤,其时间上就不如静态编译。
同时由于该绕过了该类的源码,容易对内部逻辑结构造成干扰。

三根据其特性有如下应用场景:
特性:可以动态获取正在运行程序类的属性或方法等和调用对象的方法
场景:动态代理,工厂模式优化,Java jdbc数据库操作等
下面会使用实际例子来说明该特性

四反射机制的具体实现
反射机制的实现主要通过java.lang.class类来进行操作
java.lang.class:
定义:java.lang.class类是反射机制的基础
作用:该类中存放了对应类型对象运行时的信息

前面说了,在java编译前,就已经存在于jvm中,在运行时,jvm会为运行时的类创建一个java.lang.class对象,用来维护对象的运行
而且该class中,存放着对应对象的所有运行时信息,就好比是将对该运行时对象信息的一个备份
且每个class类的实例对象的加载类都只有一个,好比每个class类都是一个模板,而该class类new出来的实例对象都是根据该模板生成的,所以即使一个class类有多个实例对象但是其getClass的结果都是一样的
如下例子

//对于2个String类型对象,它们的class对象就是同一个
Class a1="che".getClass();
Class a2=Class.forName("java.lang.class")
System.out.println(a1==a2)
//结果返回为True,因为该引用指向的是同一个Class 对象

同时Java的反射机制,除了获取最基本的Class对象,还需要获取另外三个类对象,Construction类,Method类和Field类
要这三个类的意义在于获取和调用运行时对象的构造方法,方法和属性。

使用反射机制的大致流程:
1获取目标类型的Class对象

2通过Class对象,来获取Construction类对象Method类对象Field类对象

3通过Construction类对象,Method类对象和Field类对象来获取运行时对象的构造方法方法属性,然后对其进行各种操作
接下来,我们来详解讲解每个步骤:
步骤1:获取目标类型的Class对象

//获取目标类型的class对象
//1使用Object.getClass()获取------该方法会返回一个Class类型的实例
Boolean che=true;
Class  cheType=che.getClass();
System.out.println(cheType);
//输出的结果是class  java.lang.Boolean //2Static method class.forName
Class<?>  cheType=Class.forName("java.lang.class");
//使用时,应提供异常处理器
System.out.println(cheType);
//输出结果:class  java.lang.Boolean

通过Class对象分别获得Construction类对象,Method类对象和Field类对象
/一 通过Class对象获取类的构造方法/

//重点:下面会出现declared这个词,这是公共的意思,公共类,若方法中使用了该关键字,那么取出的就只是和公共类有关系的,与继承类无关
//a获取指定的构造方法(传入构造函数的参数类型,包括公共和继承)
Constructor<T> getConstructor(Class<?>.... parameterTypes)
// b获取所有的构造方法(只包括公共)
Constructor<?>[] getConstructors()
//c获取指定的构造方法(传入构造函数的参数类型 只包含公共不包含继承)
Constructor<T> getDeclaredConstructor(Class<?>...parametrTypes)
//d获取所有的构造方法(public,private等修饰的都会获取)
Constructor <?> getDeclaredConstructors()

/二 通过Class对象获取类的方法/

//a和上面类似,获取指定的方法,就需要传入对应的方法名&参数类型,包括公共和继承
Method   getMethod(String name,Class<?> ...parameterTypes)
// b 获取公共(public)方法
Method[]   getMethods()
//c获取指定的方法
Method   getDeclaredMethod(String name,Class<?>...parametrTypes)
//d获取所有的方法(public,private等修饰的都会获取)
Method[]   getDeclaredMethods()

/三通过Class对象获取类的属性/

//a和上面类似,获取指定的属性,就需要传入对应的属性名,包括公共和继承
FIeld   getFIeld(String name)
// b获取所有的属性(只包括公共)
FIeld[]   getFIelds()
//c获取指定的属性(
FIeld   getDeclaredFIeld(Class<?>...parametrTypes)
//d获取所有的属性(public,private等修饰的都会获取)
FIeld[]   getDeclaredFIelds()

/四除了上面那些方法,还有一些比较常用的方法/

//返回完整的类名(例如java.lang.Boolean)
String getName();//创建一个实例,/调用默认的构造器,若该类无构造器,则会抛出异常/
Object newInstance()

以上我们就完成了第二步,分别获取了其他三个类对象,接下来我们就使用对应的类对象来完成对目标对象的操作

/一通过Constructor对象来获取类的构造方法并进行操作/
Modifiers//修饰符的意思

String getName();//获取构造器名
Class getDeclaringClass();//获取类中构造器的Class对象
int getModifies();//返回整型数字,用不同的位开关描述访问修饰符的使用状况,好比返回的是状态码
Class[] getExceptionTypes();//获取描述抛出的异常方法类型的Class对象数组
Class[] getParameterTypes();//获取参数类型的Class 对象数组

/二通过Method对象来获取类的方法并进行操作/

String  getName();//获取方法名
Class getDeclaringClass()://获取类中方法的Class对象
int getModifiers();//返回整型数值,用不同的状态码来描述访问修饰符的使用状况
Class getExceptionTypes();//获取用于描述抛出异常方法类型的Class对象数组
Class getParameterTypes();//获取一个用于描述参数类型的Class对象数组

/三通过Field对象来获取类的属性并进行操作/

String  getName();//获取对应的属性名
Class getDeclaringClass();//获取类中属性的Class对象
Class getType();//获取属性类型的Class对象
int getModifiers();//返回整型数值用不同的位开关来描述访问修饰符的使用状况
Object get(Object obj);//返回指定对象上,此属性的值
void set(Object obj,Object value);//给指定对象的属性赋值
//另外还有以下两个方法
//获取对应mofidiers位设置的修饰符
static String toString(int modifiers)
//检查方法名中对应的修饰符在modifiers中的值
static boolean isXXX(int modiers)

这样,我们关于Java的反射机制的大致流程就讲完了

五反射机制一定要关注的几点,简单易懂且重要
1在Java中,有一种安全机制,该机制只允许对运行时的程序进行访问操作,不允许进行修改等操作
2另外还有一种,是关于访问权限的,和封装有关,不允许访问被private修饰的方法或字段
以上两点,刚好和我们的反射机制有冲突,要想完整实现我们的反射机制,就需要脱离安全机制的管控,屏蔽掉访问权限的检查,从而为所欲为。
见下

//为了达到为所欲为的目的,我们可以采用Constructor,Method和Field的setAccessible方法来实现
//为反射机制设置可以访问的标志
void setAccessible(boolean flag)
//flagtrue时,可以脱离管控,
boolean  isAccessible()
//获得该值,判断是否已经脱离管控
static void setAccessible(AccessibleObject[] array,boolean flag)
//设置对象数组可以访问的标志,

六到这里,关于反射机制我们已经了解了,接下来我们就来进行实践吧!
实例1,利用发射机制调用类的构造方法:

package stu;public class FanShe {/** 分别创造一个无参构造器和有参构造器* */private String name;
public FanShe(){System.out.println("创建了一个无参数的反射实例");
}
public FanShe(String name){System.out.println("创建了一个有参数的反射实例");
}
}
------------------------------------------------------------------------------------------
package stu;import java.lang.reflect.InvocationTargetException;public class MainTest{   //获取FanShe的Class对象public static void main(String args[]) {
Class fansheClass=FanShe.class;//通过Class对象获取Constructor类对象,从而调用无参构造方法(反射机制中,创建对象是使用newInstance(),此方法和new很像)
try{
Object obj1=fansheClass.getConstructor().newInstance();
Object obj2=fansheClass.getConstructor(String.class).newInstance("name");
}
catch(InstantiationException e){e.printStackTrace();
}
catch(IllegalAccessException e){e.printStackTrace();
}
catch(InvocationTargetException e){e.printStackTrace();
}
catch(NoSuchMethodException e){e.printStackTrace();
}
}
}------------------------------执行结果
创建了一个无参数的反射实例
创建了一个有参数的反射实例

实例2:利用反射机制调用类对象的方法

package stu;public class FanShe2 {private String name;public FanShe2(){System.out.println("使用反射机制来获取类对象的属性");}
}
---------------------------------------------
package stu;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;public class MainTest2 {public static void main(String args[]){//1获取Fanshe2的Class类对象Class f2class=FanShe2.class;try{//2通过Class对象来创建FanShe2类的对象Object object1=f2class.newInstance();//3通过Class对象和Field类对象来获得FanShe2类的name属性Field f=f2class.getDeclaredField("name");//4设置私有访问权限,脱离管控f.setAccessible(true);//5通过Field的类对象对新创建的FenShe2对象object1的name属性设置值,void set(Object obj,Object value)f.set(object1, "成功赋值");//6获取新创建FanShe2对象的name属性&输出System.out.println(f.get(object1));}catch(InstantiationException e){e.printStackTrace();
}catch(IllegalAccessException e){e.printStackTrace();
} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();
} catch (NoSuchFieldException e) {// TODO Auto-generated catch blocke.printStackTrace();
}}
}
-----------------------执行结果
使用反射机制来获取类对象的属性
成功赋值

实例3:利用反射机制来调用类对象的方法

package stu;
/** 分别创建一个无参和一个有参的方法*/
public class FanShe3 {public FanShe3(){System.out.println("通过反射机制来调用类对象的方法");}public void Test1(){System.out.println("Test1 我是一个无参方法");}public void Test2(String str){System.out.println("Test2 我是一个名为"+str+"有参方法");}
}
-----------------------------------------------------------------
package stu;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class MainTest3 {public static void main(String args[]){//1创建FanShe3类的Class对象Class f3class=FanShe3.class;try {//2通过Class类,创建FanShe3类的对象Object object=f3class.newInstance();//3通过Class对象获取Test1()方法:需要传入方法名Method test11=f3class.getMethod("Test1");//4通过Class对象获取Test2()方法:需要传入方法名&参数类型Method test22=f3class.getMethod("Test2", String.class);//5通过Method对象,传入对应的参数,.invoke调用的意思,调用FanShe3对应的方法test11.invoke(object);test22.invoke(object, "Rapper");}  catch(InstantiationException e){e.printStackTrace();}catch(IllegalAccessException e){e.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();}  catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
-----------------------------执行结果
通过反射机制来调用类对象的方法
Test1 我是一个无参方法
Test2 我是一个名为Rapper有参方法

此致,Java的反射机制,就已经完全讲解清楚了,

Java的反射机制,内含超简单实例代码(搞懂反射,这一篇就够了)相关推荐

  1. 小球碰壁反弹加分_用Java实现小球碰壁反弹的简单实例(算法十分简单)

    用Java实现小球碰壁反弹的简单实例(算法十分简单) 核心代码如下: if(addX){ x+=3; }else{ x-=3; } if(addY){ y+=6; }else{ y-=6; } if( ...

  2. 安卓Android ViewModel 超简单实例

    安卓Android ViewModel 超简单实例 文章目录 安卓Android ViewModel 超简单实例 前言 使用步骤 1.引入库 2.继承ViewModel 并定义一个对象 3.到处去用 ...

  3. ajax简单实例代码,分享Ajax创建简单实例代码

    XmlHttp是一套可以在Javascript.VbScript.Jscript等脚本语言中通过http协议传送或从接收XML及其他数据的一套API.XmlHttp最大的用处是可以更新网页的部分内容而 ...

  4. android扫码 超简单零代码

    android扫码 超简单零代码 小序 背景介绍 前期准备 zxing和华为扫码服务对比 开始搬运 结语 小序 这是一篇纯新手教学,本人之前没有任何安卓开发经验(尴尬),本文也不涉及任何代码就可以使用 ...

  5. android handler的机制和原理_一文搞懂handler:彻底明白Android消息机制的原理及源码

    提起Android消息机制,想必都不陌生.其中包含三个部分:Handler,MessageQueue以及Looper,三者共同协作,完成消息机制的运行.本篇文章将由浅入深解析Android消息机制的运 ...

  6. Java反射Method和Field简单实例

    目录 定义 使用方法 1.Field 2.Method 3.简单实例 定义 JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方 ...

  7. java中定时任务和线程池_java基于线程池和反射机制实现定时任务完整实例

    本文实例讲述了java基于线程池和反射机制实现定时任务的方法.分享给大家供大家参考,具体如下: 主要包括如下实现类: 1. Main类: 任务执行的入口: 调用main方法,开始加载任务配置并执行任务 ...

  8. Java反射机制和动态代理实例

    反射机制是Java语言的一个重要特性,允许用户动态获取类的信息和动态调用对象的方法. 通过给定类的名字,通过反射机制就可以获取类的所有信息. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道 ...

  9. java最美验证码_java超简单,超级实用验证码

    java超简单,超级实用验证码 1.   验证码(2) dsnaValidateCode.jar dsnaValidateCode_src.rar ValidateCode.java 验证码生成类 J ...

最新文章

  1. 虚拟机+ubuntu 图形界面和终端界面的切换
  2. JAVA spring配置文件总结
  3. Python字典中你必须知道的用法
  4. 音视频技术开发周刊 | 193
  5. yii2笔记: 单元测试
  6. [Redis6]常用数据类型_List列表
  7. 克鲁斯卡尔算法(公交站问题)
  8. 不支持对系统目录进行即席更新_「目录」让你的文档结构一目了然
  9. eq linux_《Linux设备驱动程序》(十二)——时间操作(一)
  10. IntelliJ IDEA2019.1.2汉化包
  11. SVM学习总结(三)SMO算法流程图及注释源码
  12. 一文搞懂浏览器缓存机制
  13. rjs子模板中如何按照顺序并且有序列地执行语句
  14. 修改基于formView的MFC单文档背景颜色
  15. C# 秒转时分秒方法
  16. 丰沛数_不足数_完全数
  17. 沈阳贫民窟男孩的5条择偶观
  18. openwrt的luci应用ipk包开发(二)
  19. 研发团队如何借助Gitlab来做代码review
  20. wifi设置代理解决play商店“正在等待下载”问题;pixel 2 无法更新问题解决

热门文章

  1. Word2016自定义快速访问工具栏将最常用的命令或者工具添加进去
  2. 开关电源中电感啸叫的原因
  3. 计算机 游戏化 论文,计算机程序设计类课程游戏化探究
  4. python使用tqdm显示进度表
  5. NLP 神经--语言程序
  6. win7win10进入高级启动选项方法
  7. csdn t恤_谁知道那里有100美元的T恤市场
  8. CCNA考试科目、内容、费用等相关信息
  9. offset元素偏移量
  10. 项目中所了解的一些浏览器之间的差异