1.什么是反射?
反射是一种机制,利用反射机制动态的实例化对象、读写属性、调用方法、构造函数。
java反射是在jvm虚拟机里面进行的,它更多的是用作于框架中。
2.如何得到类对象?
一切反射相关的代码都从获得类对象开始
3种获取方式:
2.1 类名.class;
Class<Student> student02 = Student.class;
2.2 对象名.getClass();
Class<Student> student01 = (Class<Student>) Class.forName("com.zking.jee08.Student");
2.3 Class.forName(全限定名/全路径名)
Student student = new Student(); Class<Student> student03 = (Class<Student>) student.getClass();
3.根据类得到类名(全限定名/全路径名)
1)cName.getName(); -->获取全限定名
2)cName.getSimpleName(); -->获取类名
3)cName.getPackage(); -->获取包名
4.根据类得到类的属性
Field field=cla.getField(“属性名”);
field.getName(); -->获取属性名
filed.getType(); -->获取属性类型
field.getModifiers(); -->获取属性访问修饰符
field.set(Object,Object); -->设置属性值,参数1:要设置属性所在对象;参数2:要设置值;
field.get(Object); -->获取属性值,参数:要获取属性值的对象
field.getDeclaredField(“属性名”); -->获取单个属性(私有、公有、受保护、默认、静态)
field.getDeclaredFields(); -->获取所有属性(私有、公有、受保护、默认、静态)
我的实体类->Student
package com.zking.relfect.entity; public class Student { private String sid; private String sname; public Integer age; String sex; 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()); } }
获取对象方式:第一种直接new,第二种通过反射的方式来获取对象
//直接new获取对象 Student student04 = new Student(); //通过反射的方式获取对象 Class<Student> Student05 = Student.class; Student stu= Student05.newInstance();//调用无参的构造方法,开始实例化 stu.setSid("01"); stu.setSname("张三"); System.out.println(stu.getSname());
new与.newInstance的区别:
new等同于初始化+实例化
.newInstance等于实例化,在使用newInstance时首先必须先加载才能使用,在框架里面使用比较多
通过Constructor来获取函数
注意:Constructor方法只能获取公开构造方法,并不能获取私有的构造方法
Constructor<Student> stu= Student05.getConstructor(String.class); Student stu01 = stu.newInstance("02");//开始实例化 System.out.println(stu01.getSid());
通过getDeclaredConstructor来获取私有的构造方法
在我们使用getDeclaredConstructor时不管是公开的构造方法还是私有的构造方法都能获取但是在我们调用了这个方法后还需要一步,要打开访问权setAccessible(true); true的意思为打开权限
Constructor<Student> stu04= Student05.getDeclaredConstructor(Integer.class); stu04.setAccessible(true);//打开访问权限 Student stu004 = stu04.newInstance(1); System.out.println(stu004.getAge());
如何调用反射方法
注意: 在调用反射方法的时候需要先加载反射
//加载反射 @SuppressWarnings("unchecked") Class<Student> student = (Class<Student>) Class.forName("com.zking.jee08.Student"); Student stu= student.newInstance(); stu.setSid("01"); stu.setSname("张三");
开始调用反射方法
getMethod("hello", String.class)里面hello是student里面的一个方法,String.class是hello方法的参数
注意:在调用方法方法时,方法参数必须也要使用反射
//通过反射调用hello无参方法 Method stu01 = student.getMethod("hello"); //开始加载对象 Student in01 = (Student) stu01.invoke(stu);//stu是实例化对象,要在哪个实例化对象里面加载 System.out.println(in01); //通过反射调用hello有参的方法 Method stu02 = student.getMethod("hello", String.class); //开始加载对象 Student in02= (Student) stu02.invoke(stu,"张三"); System.out.println(in02);
如何调用反射属性
调用反射属性与调用反射方法基本一致
首先需要加载反射
//加载反射 @SuppressWarnings("unchecked") Class<Student> student = (Class<Student>) Class.forName("com.zking.jee08.Student"); Student stu = student.newInstance(); stu.setSid("01"); stu.setSname("张三"); stu.setAge(10);
开始动态调用属性
getDeclaredField是调用单个属性,注意:我这里是DeclaredField,既可以调用私有属性也可以调用公开的属性,需要设置setAccessible(true);
//定义获取sid属性值 Field f1 = student.getDeclaredField("sid"); f1.setAccessible(true); //从stu对象里面获取属性值 String get1 = (String) f1.get(stu);//stu是实例化对象,要在哪个实例化对象里面调用属性 System.out.println(get1);
一次性获取多个属性
Field[] f4 = student.getDeclaredFields(); for (Field f : f4) { f.setAccessible(true); System.out.println(f.getName() +":" + f.get(stu));//stu是实例化对象,要在哪个实例化对象里面调用属性 }
5.根据类得到类的方法
//无参无返回、无参有参会、有参无返回、有参有返回
cla.getMethod(); -->获取单个公有方法
cla.getDeclaredMethod(); -->获取当个方法(包括私有、受保护、默认、公有)
cla.getMethods(); -->获取所有公有方法
cla.getDeclaredMethods(); -->获取所有的方法(包括私有、受保护、默认、公有)
6.根据类得到类的构造方法
cla.getConstrutor(); -->获取单个公有构造方法
cla.getDeclaredConstrutor(); -->获取单个构造方法(包括私有、受保护、默认、公有)
cla.getConstrutors(); -->获取所有的公有构造方法
cla.getDeclaredConstrutors(); -->获取所有的构造方法(包括私有、受保护、默认、公有)
7.根据类得到类的实现接口列表
Class[] interface=cla.getInterfaces(); -->获取类对象中所有实现接口列表