反射
1.什么是反射
引用:
之前如何使用类和对象
定义类,使用的时候是类的实例(对象)
User类(构造方法,属性,方法......)
User user = new User();
在哪用就创建改类的对象使用即可
问题:
如果仅仅知道一个类的类名,能否动态得到类的定义信息,包括哪些方法, 属性等?
类名:就是类在项目中的地址,通过地址找到类,就可以动态获得类的信息
以前在哪用,在哪new、这样的话,代码就写死的
但是一个框架需要处理不同的类,都需要能够进行处理
mybatis框架可以写一个方法,接收一个类的地址,就可以根据类的地址创建该类的对象,这样框架就可以实现以不变应万变
如何实现,反射机制
反射:在程序运行的过程中,可以动态获取类的信息,以及创建类的对象,以及调用对象中的数下方法
作用:动态获取类的信息(类地址)
好处:写一个方法,可以处理任何类
2.反射基本用法
如何动态获得类的信息
new Class()
User.java -->user.class--->一旦是用了User类,就会加载字节码文件切该类创建一个Class类的对象,我们可以通过该类的Class类的对象,获得类中的信息
-
要使用Class类的方法,必须先获得该类的Class类的实例,获得Class
类实例的常用方法有如下三种
1.Object类中的getClass方法:适用于通过对象获得Class实例的情况
//1.通过对象名获取到类的class对象 User user = new User(); Class c1 = user.getClass();
2.类名.class方式:适用于通过类名获得Class实例的情况
Class c2 = User.class;
3.Class类的静态方法 forName(String name)
//3.通过Class.forName(“类的地址”) String cname = "com.ffyc.javaReflect.Car"; Class c3 = Class.forName(cname);
Constructor类
获得类中的构造方法 Constructor constructor = c.getConstructor();//获得类中无参构造方法,获得公共权限构造方法 getDeclaredConstructor(类<?>...parameterTypes)//可以获得私有的无参构造方法
Constructor constructor = c.getDeclaredConstructor();//私有无参构造方法 constructor.setAccessible(true);//设置对私有权限构造方法进行操作 Object object = constructor.newInstance();//通过无参构造方法创建对象
Constructor constructor1 = c.getConstructor(int.class,String.class);//获得有参构造方法
Object object1 = constructor1.newInstance(10,"jim");//通过有参构造方法创建对象
Field类作用
对于类中的属性进行赋值
Map<String,Object> map = new HashMap<>(); map.put("id",100); map.put("name","tom"); //获得类中所有的属性 Field[] fields = c.getDeclaredFields(); for (Field f : fields){//循环属性 f.setAccessible(true); f.set(object,map.get(f.getName())); } System.out.println(object);
Method类的作用
获得类中的方法
getMethods()获得类中所有公共的成员方法
getMethod("getId",type);获得公共的指定名称参数的成员方法
getDeclaredMethods();获得类中所有(包含私有的)的成员方法
getDeclaredMethod("getId",type)获得所有的指定名称参数的成员方法
Method method = c.getMethod("setId",int.class); method.invoke(object,100); System.out.println(object);
反射案例
创建一个Car类和User类将其转json工具类
Car类:
package com.ffyc.javaReflect; public class Car { private int no; private String color; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Car(int no, String color) { this.no = no; this.color = color; } public Car() { System.out.println("car无参构造方法"); } @Override public String toString() { return "Car{" + "nu=" + no + ", color='" + color + '\'' + '}'; } }
User类
package com.ffyc.javaReflect; public class User { private int id; private String name; private User() { System.out.println("user无参构造"); } public User(int id, String name) { this.id = id; this.name = name; System.out.println("User有参构造"); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
转json工具类
package com.ffyc.javaReflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test5 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //自定义java对象专json工具类 User user = new User(100,"tom"); Car car = new Car(200,"蓝色"); String json = Test5.objectToJson(user); String json1 = Test5.objectToJson(car); System.out.println(json); System.out.println(json1); //{"name":tom,id:10} } public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { String s = "{"; Class c = object.getClass(); Field[] fields = c.getDeclaredFields(); for (Field f : fields){ /* f.getName()属性名字 c.getMethod(check(f.getName()))获得指定属性名称的get方法 invoke(object)调用get方法 */ s+=f.getName()+":"+c.getMethod(check(f.getName())).invoke(object)+","; } s = s.substring(0,s.length()-1); s+="}"; return s; } public static String check(String fieldName){ String methodName = "get" + String.valueOf(fieldName.charAt(0)).toUpperCase()+fieldName.substring(1); return methodName; } }