反射

mac2022-06-30  24

概述;

什么是反射Class对象的获取方式获取Class对象的信息反射操作Constructor反射获取Method并使用反射获取Field并使用

1.什么是反射

什么是反射?

在程序运行的过程中,通过Class对象得到类中的信息构造方法,成员变量,成员方法,并操作他们.

反射的应用场景?

常见的有: idea的智能提示、框架等(通过反射技术对象类进行了解剖得到了类的所有成员。)

使用反射操作类成员的前提

要获得该类字节码文件对象,就是Class对象

2. Class对象的获取方式

三种获取Class对象的方式

类名.class对象.getClass()Class.forName(类全名); 注意: 这三种方式获取的是同一个Class对象

提供一个Employee类

public class Employee { private String name; private int age; public String weight; public double height; private int sleep(int hour) { System.out.println("睡了" + hour + "小时"); return hour * 2; } } //省略getset构造方法

获取class

@Test public void test01() throws ClassNotFoundException { // 类名.class Class<Employee> cls1 = Employee.class; System.out.println("cls1 = " + cls1); // 对象.getClass() Employee e = new Employee(); Class<? extends Employee> cls2 = e.getClass(); System.out.println("cls2 = " + cls2); // Class.forName(类全名); // 类全名就是: 包名.类名 Class<?> cls3 = Class.forName("com.bean.Employee"); System.out.println("cls3 = " + cls3); System.out.println(cls1 == cls2); System.out.println(cls1 == cls3); }

3.获取Class对象的信息

Class类中的方法:

String getName(); 获取类全名 com.bean.EmployeeString getSimpleName(); 获取类名 EmployeenewInstance(); 创建对象 public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> cls = Class.forName("com.bean.Employee"); // String getName(); System.out.println(cls.getName()); // com.itheima.bean.Employee // String getSimpleName(); System.out.println(cls.getSimpleName()); // Employee Object o = cls.newInstance(); // 使用无参构造创建对象 System.out.println(o); // com.bean.Employee@64c64813 }

4.反射操作Constructor

1.Constructor类作用:

表示类中的构造方法

2.如何得到public的Constructor对象:

1.得到这个类的Class对象 2.通过Class对象获取public构造方法

3.Constructor类的方法:

Object newInstance(); 通过构造方法创建对象

4.基本数据类型与引用数据类型的Class对象

Integer.class != int.class

5.获取public的构造方法?

getConstructors: 获取所有的public的构造方法 getConstructor: 获取一个public的构造方法

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // 1.得到这个类的Class对象 Class<?> cls = Class.forName("com.bean.Employee"); // 2.通过Class对象获取public构造方法 // getConstructors: 获取所有的public的构造方法 Constructor<?>[] cs = cls.getConstructors(); for (Constructor<?> c : cs) { System.out.println("c = " + c); } System.out.println("------------"); // getConstructor: 获取一个public的构造方法 Constructor<?> c1 = cls.getConstructor(); System.out.println("c1 = " + c1); // Object newInstance(); 通过构造方法创建对象 Object o = c1.newInstance(); System.out.println("o = " + o); Constructor<?> c2 = cls.getConstructor(String.class, int.class); System.out.println("c2 = " + c2); Object o2 = c2.newInstance("凤姐", 18); System.out.println("o2 = " + o2); }

通过反射获取声明的Constructor

只要类中有的,不管权限

1.如何得到声明的Constructor

1.获取Class对象 2.通过Class对象获取声明的Constructor

2.Declared的规律

没有Declared获取public的有Declared获取声明的

3.对私有构造方法我们在使用之前调用

dc1.setAccessible(true); // 设置可访问为true

4.如何得到声明的Constructor?

getDeclaredConstructors: 获取所有声明的构造方法getDeclaredConstructor: 获取一个声明的构造方法 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // 1.获取Class对象 Class<?> cls = Class.forName("com.bean.Employee"); // 2.通过Class对象获取声明的Constructor // Declared:表示声明的 // getDeclaredConstructors: 获取所有声明的构造方法 Constructor<?>[] dcs = cls.getDeclaredConstructors(); for (Constructor<?> dc : dcs) { System.out.println("dc = " + dc); } System.out.println("-------------"); // getDeclaredConstructor: 获取一个声明的构造方法 Constructor<?> dc1 = cls.getDeclaredConstructor(String.class); System.out.println("dc1 = " + dc1); // 暴力反射 dc1.setAccessible(true); // 设置可访问为true Object obj = dc1.newInstance("凤姐"); // IllegalAccessException: 非法访问异常 System.out.println("obj = " + obj); Constructor<?> dc2 = cls.getDeclaredConstructor(int.class); System.out.println("dc2 = " + dc2); }

5.反射获取Method并使用

1.Method类作用

表示类中的方法

2.如何得到Method对象

1.获取Class对象 2.通过Class对象获取Method

getMethods: 获取所有public的方法(包含父类的)getMethod: 获取一个public的方法getDeclaredMethods: 获取所有声明的方法getDeclaredMethod: 获取一个声明的方法

3.Method类中的方法

Object invoke(Object obj, Object… args): 执行, 可以调用这个方法Object obj: 调用方法的对象Object… args: 调用方法的参数返回值Object: 方法的返回值

3.Method如何执行

invoke

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { // 1.获取Class对象 Class<?> cls = Class.forName("com.bean.Employee"); Employee e = new Employee(); // 2.通过Class对象获取Method // getMethods: 获取所有public的方法(包含父类的) Method[] ms = cls.getMethods(); for (Method m : ms) { System.out.println("m = " + m); } System.out.println("-------------"); // getMethod: 获取一个public的方法 Method m1 = cls.getMethod("setName", String.class); System.out.println("m1 = " + m1); // Object invoke(Object obj, Object... args): 执行, 可以调用这个方法 // Object obj: 调用方法的对象 // Object... args: 调用方法的参数 // 返回值Object: 方法的返回值 Object r1 = m1.invoke(e, "凤姐"); System.out.println("返回值1: " + r1); // null System.out.println("e = " + e); System.out.println("----------"); // getDeclaredMethods: 获取所有声明的方法 Method[] dms = cls.getDeclaredMethods(); for (Method dm : dms) { System.out.println("dm = " + dm); } System.out.println("-----------"); // getDeclaredMethod: 获取一个声明的方法 Method m2 = cls.getDeclaredMethod("sleep", int.class); System.out.println("m2 = " + m2); m2.setAccessible(true); Object r2 = m2.invoke(e, 10); System.out.println("返回值2: " + r2); }

6.反射获取Field并使用

1.Field类的作用:

表示类中的成员变量

2.如果获取Field:

1.获取Class对象 2.通过Class对象获取Field

3.Field的操作:

给成员变量赋值基本数据类型: setXxx setInt,setDouble引用数据类型: set

获取成员变量的值

基本数据类型: getXxx getInt,getDouble引用数据类型: get

4.如何获取Field?

getFields: 获取所有public的成员变量getField: 获取一个public的成员变量getDeclaredFields: 获取所有声明的成员变量getDeclaredField: 获取一个声明的成员变量 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException { // 1.获取Class对象 Class<?> cls = Class.forName("com.bean.Employee"); Object obj = cls.newInstance(); // 2.通过Class对象获取Field // getFields: 获取所有public的成员变量 Field[] fs = cls.getFields(); for (Field f : fs) { System.out.println("f = " + f); } System.out.println("-----------"); // getField: 获取一个public的成员变量 Field f1 = cls.getField("weight"); System.out.println("f1 = " + f1); // 赋值 f1.set(obj, "99KG"); System.out.println("obj = " + obj); // 获取值 Object weight = f1.get(obj); System.out.println("weight = " + weight); System.out.println("-----------"); // getDeclaredFields: 获取所有声明的成员变量 Field[] dfs = cls.getDeclaredFields(); for (Field df : dfs) { System.out.println("df = " + df); } System.out.println("-----------"); // getDeclaredField: 获取一个声明的成员变量 Field f2 = cls.getDeclaredField("age"); System.out.println("f2 = " + f2); f2.setAccessible(true); // 赋值 f2.setInt(obj, 18); System.out.println("obj = " + obj); // 获取值 int age = f2.getInt(obj); System.out.println("age = " + age); Class<?> type = f2.getType(); System.out.println("type = " + type); // type = int }
最新回复(0)