jvm|Java的反射机制ヾ(≧▽≦*)o

目录
反射
反射的概念
反射的优点和缺点
优点:
缺点:
解决方案:
Class类
Class类的概念
获取Class对象的三种方法
反射实例化对象
用方法反射调
反射读写属性
反射 反射的概念

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
——————百度百科
反射是Java语言中的一种机制,通过这种机制可以动态地实例化对象、读写属性、调用方法
反射的优点和缺点 优点:
  • 能够运行时动态获取类的实例,提高灵活性;
  • 与动态编译结合;
缺点:
  • 使用反射性能较低,需要解析字节码(.class文件),将内存中的对象进行解析;
  • 相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性);
解决方案:
  • 通过setAccessible(true)关闭JDK的安全检查来提升反射速度;
  • 多次创建一个类的实例时,有缓存会快很多;
  • ReflectASM工具类,通过字节码生成的方式加快反射速度 ;
Class类 Class类的概念
【jvm|Java的反射机制ヾ(≧▽≦*)o】Class类是一个比较特殊的类,它是反射机制的基础,Class类的对象表示正在运行的Java程序中的类或接口,也就是任何一个类被加载时,即将类的.class文件(字节码文件)读入内存的同时,都自动为之创建一个java.lang.Class对象。Class类没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()方法创建的,因此不能显式地创建一个Class对象。通过这个Class对象,才可以获得该对象的其他信息。
——————百度百科
获取Class对象的三种方法 这里我会写一个学生类为例子
package com.zking.reflex; public class Student { private String sid; private String sname; public Integer age; static{ System.out.println("加载进jvm中!"); } @Override public String toString() { return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]"; } public Student() { super(); System.out.println("调用无参构造方法创建了一个学生对象"); } public Student(String sid) { super(); this.sid = sid; System.out.println("调用带一个参数的构造方法创建了一个学生对象"); } public Student(String sid, String sname) { super(); this.sid = sid; this.sname = sname; System.out.println("调用带二个参数的构造方法创建了一个学生对象"); } @SuppressWarnings("unused") private Student(Integer age) { System.out.println("调用Student类私有的构造方法创建一个学生对象"); this.age = age; } public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public void hello() { System.out.println("你好!我是" + this.sname); } public void hello(String name) { System.out.println(name + "你好!我是" + this.sname); } @SuppressWarnings("unused") private Integer add(Integer a, Integer b) { return new Integer(a.intValue() + b.intValue()); } }

?获取的方法
大家注意了,这里我们需要填类的权限命名 ,获取命名的方法如下图片所示:
首先点开学生类(例子), 鼠标右键点击绿色的Student,选择Copy Qualified Name,类的权限命名就拿到了。
jvm|Java的反射机制ヾ(≧▽≦*)o
文章图片

然后复制到Class.forName(),的括号里就完成了。
package com.zking.reflex; public class Demo { @SuppressWarnings("rawtypes") public static void main(String[] args) throws Exception { //1.通过 Class.forName(类的权限命名) 获取Class Class clazz = (Class)Class.forName("com.zking.reflex.Student"); //2.通过 类.class 获取Class Class clazz02 = Student.class; //3.通过 对象.getClass() 获取Class Student stu = new Student(); Class clazz03 = stu.getClass(); System.out.println(clazz); System.out.println(clazz02); System.out.println(clazz03); } }

运行结果:
jvm|Java的反射机制ヾ(≧▽≦*)o
文章图片

获取的值都是一样的。
反射实例化对象 还是以学生类为例子
//通过反射实例化对象 //1.调用无参构造方法 Constructor c1 = clazz.getConstructor(); Student stu01 = c1.newInstance(); stu01.setSname("纪念品"); System.out.println(stu01); //2.调用带一个参数的构造方法 Constructor c2 = clazz.getConstructor(String.class); Student stu02 = c2.newInstance("001"); stu02.setSname("流浪者"); System.out.println(stu02); //3.调用带两个参数的构造方法 Constructor c3 = clazz.getConstructor(String.class,String.class); Student stu03 = c3.newInstance("002","小女巫"); System.out.println(stu03); //4.调用私有的方法 //Declared 可以获取公共的或私有的属性或方法 Constructor c4 = clazz.getDeclaredConstructor(Integer.class); c4.setAccessible(true); Student stu04 = c4.newInstance(18); System.out.println(stu04);

用方法反射调
Method method = clazz.getMethod("hello"); stu04.setSname("lihao"); //调用方法 method.invoke(stu04); Method method02 = clazz.getMethod("hello",String.class); method02.invoke(stu04, "zengfanyan"); //获取私有方法 Method method03 = clazz.getDeclaredMethod("add",Integer.class, Integer.class); method03.setAccessible(true); int rv = (int)method03.invoke(stu04, 1,1); System.out.println(rv);

反射读写属性
Field f = clazz.getField("age"); f.set(stu04, 78); System.out.println(stu04); System.out.println(f.get(stu04)); //获取私有属性 Field f01 = clazz.getDeclaredField("sname"); f01.setAccessible(true); //调用属性 f01.set(stu04, "lihao is hao ren"); System.out.println(stu04);

补充:
Bean对象
除了上述获取属性的方法之外,还可以通过BeanUtil.getproperty(对象名,“属性”)的方式获取属性,其原理是先调用类中的公开get属性的方法获取再通过反射机制进行获取
好了,这篇文章就到这里结束了,拜拜!
jvm|Java的反射机制ヾ(≧▽≦*)o
文章图片

    推荐阅读