反射应用在一些通用性比较高的代码中
框架大多数是使用反射来实现的
** 在框架开发中都是基于配置文件开发
在配置文件中通过反射得到类中所有内容,可以让类中的某个方法来执行
-
类中的所有内容包括构造方法,普通方法,有参无参
反射的原理:
代码.java----->代码.class------->使用jvm的类加载器在jvm中解析字节码文件------->在jvm中有专门的Class类来表示解析完成的字节码文件
得到Class类中的数据即可实现对类中的属性,有参无参构造方法,普通方法的操作
使用反射首先需要得到Class类
三种方式
-
类名.class
-
对象.getClass()
-
使用Class.forName("路径")
反射类型:
属性:Field
构造方法:Constructor
普通方法:Method
示例:使用反射操作实体类
实体类:
package com.ahrtolia.testreflex;
/*
*@ClassName person
*@Description TODO
*@Author ahrtolia
*@Date 2019/8/7 22:17
*@Version 1.0
*/
public class Person {
private String name;
private int age;
public Person(){}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
反射:
package com.ahrtolia.testreflex;
/*
*@ClassName Demo1
*@Description TODO
*@Author ahrtolia
*@Date 2019/8/7 22:26
*@Version 1.0
*/
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo1 {
public static void main(String[] args) throws Exception{
// 得到class类的三种方法
Class clazz1 = Person.class;
Class clazz2 = new Person().getClass();
Class clazz3 = Class.forName("com.ahrtolia.testreflex.Person"); //自动合成的默认构造器
}
// 操作有参构造方法
@Test
public void test2() throws Exception{
// 得到Class
Class c1 = Person.class;
// 使用有参构造方法
// 可以获得所有的构造方法
// c1.getConstructors();
Constructor cs = c1.getConstructor(String.class, int.class);
// 通过有参构造方法设置值
// 通过有参构造方法创造Person实例
Person p1 = (Person) cs.newInstance("lisi", 20);
System.out.println(p1.getName()+"---"+p1.getAge());
}
// 操作无参构造方法
@Test
public void test1() throws Exception{
// 得到Class
Class c2 = Class.forName("com.ahrtolia.testreflex.Person");
// 得到Person实例
Person p = (Person) c2.newInstance();
// 设置参数
p.setName("张三");
// 得到参数
System.out.println(p.getName());
}
// 操作属性
@Test
public void test3(){
try {
// 得到class
Class c3 = Person.class;
// 得到所有属性
// c3.getDeclaredFields();
// 得到其中那么name属性
Field f1 = c3.getDeclaredField("name");
// 得到Person实例
Person p2 = (Person) c3.newInstance();
// 设置name值
// 将私有属性解除
// f1.setAccessible(true);
f1.set(p2, "王五");//----》p.name = "王五"
System.out.println(f1.get(p2));
}catch (Exception e){
e.printStackTrace();
}
}
// 使用反射操作普通方法
@Test
public void test4() throws Exception{
// 得到Class类
Class c4 = Class.forName("com.ahrtolia.testreflex.Person");
// 得到Person实例
Person p4 = (Person) c4.newInstance();
// 得到普通方法
// 两个参数,第一个是方法名称,第二个是通过方法设置的值
Method m1 = c4.getDeclaredMethod("setName", String.class);
// 执行方法
// 第一个参是类的实例,第二个参是属性值
m1.invoke(p4,"王五");
System.out.println(p4.getName());
}
}