反射机制入门
一、什么是反射机制?
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,
可以了解任意一个对象所属的类,
可以了解任意一个类的成员变量和方法,
可以调用任意一个对象的属性和方法。
这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
二、获取Class类型对象的三种方式
public static void main(String[] args) { Class c1 = null; try { //第一种方式:Class.forName("完整类名"); c1 = Class.forName("java.lang.String"); Class c2 = Class.forName("java.util.Date"); } catch (ClassNotFoundException e) { e.printStackTrace(); } //第二种方式:类名.class Class c3 = java.lang.String.class; /** * 第三种方式: * 先创建对象,拿到对象的引用 * 调用对象的getClass方法拿到Class对象 */ String s = new String(); Class c4 = s.getClass(); System.out.println(c1 == c3);//true System.out.println(c3 == c4);//true,说明两个对象的内存地址是一样的 }
三、反射获取属性Filed
User类:
class User { private String name; private Integer age; private String sex; }
反射获取User对象:
public static void main(String[] args) throws Exception { Class<?> demo = Class.forName("User"); Object obj = demo.newInstance(); // 获取这个对象 Class<?> objClass = obj.getClass(); // 获取到所有的属性 Field[] fields = objClass.getDeclaredFields(); for (Field field : fields) { // 获取修饰符 int i = field.getModifiers(); String modifier = Modifier.toString(i); // 获取属性类型 Class<?> type = field.getType(); String simpleName = type.getSimpleName(); // 获取属性名 String fieldName = field.getName(); System.out.println(modifier + " " + simpleName + " " + fieldName); } }
输出结果:
private String name private Integer age private String sex
设置类中某个具体属性的属性值:
public static void main(String[] args) throws Exception { Class user = Class.forName("User"); // 获取这个属性 Field name = user.getDeclaredField("name"); Field age = user.getDeclaredField("age"); // 获取要修改的对象 Object obj = user.newInstance(); // 开启属性的私有访问权限 name.setAccessible(true); age.setAccessible(true); // 设置值 name.set(obj, "lisi"); age.set(obj, 24); // 打印 System.out.println(name.get(obj)); System.out.println(age.get(obj)); }
输出结果:
lisi 24
四、反射获取方法
测试类:
class MethodDemo { public void m1() { } public static int m2(int i) { return i; } }
反射获取类中的方法:
public static void main(String[] args) throws Exception { // 获取类 Class<?> methodDemo = Class.forName("MethodDemo"); // 获取到所有的方法 Method[] methods = methodDemo.getDeclaredMethods(); for (Method method : methods) { // 获取方法修饰符 String modifier = Modifier.toString(method.getModifiers()); System.out.print(modifier + " "); Class<?> returnType = method.getReturnType(); // 获取方法返回值类型 String returnTypeSimpleName = returnType.getSimpleName(); System.out.print(returnTypeSimpleName + " "); // 获取方法的方法名 String methodName = method.getName(); System.out.print(methodName + " ( ) {\n}\n"); // 获取方法的形参参数列表 Class<?>[] parameterTypes = method.getParameterTypes(); for (Class<?> parameterType : parameterTypes) { // 获取到的是每一个形参的类型 String simpleName = parameterType.getSimpleName(); System.out.println(simpleName); } } }
结果:
反射获取某个类的某个特定方法:
import java.lang.reflect.Method; /** * @author zhangzhixi * @date 2021-5-5 9:35 */ public class Test04_获取类的某个方法 { public static void main(String[] args) throws Exception { // 1.获取这个类 Class<?> methodDemo = Class.forName("ObtainMethodDemo"); // 2.要想通过反射执行方法,得先创建这个对象 Object obj = methodDemo.newInstance(); // 3.获取某个类的某个特定方法 Method m2 = methodDemo.getMethod("m2", int.class); Method m1 = methodDemo.getMethod("m1", null); // 4.执行方法,传入参数 m1.invoke(obj, null); Object invoke = m2.invoke(obj, 666); System.out.println("返回值是:" + invoke); } } class ObtainMethodDemo { public void m1() { System.out.println("m1方法执行==>hello"); } public static int m2(int i) { return i; } }
测试结果:
m1方法执行==>hello 返回值是:666
反射获取类的构造方法:
import java.lang.reflect.Constructor; /** * @author zhangzhixi * @date 2021-5-5 9:49 */ public class Test05_获取某个类的某个构造方法 { public static void main(String[] args) throws Exception { // 1.获取class对象 Class<?> student = Class.forName("Student"); // 2.获取特定的构造方法 Constructor<?> constructor = student.getDeclaredConstructor(String.class, Integer.class); Constructor<?> studentConstructor = student.getConstructor(); // 3.执行构造 studentConstructor.newInstance(); Object newInstance = constructor.newInstance("张三", 23); System.out.println(newInstance); } } class Student { private String name; private Integer age; public Student() { System.out.println("student的无参构造方法执行!"); } public Student(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
测试结果:
student的无参构造方法执行! Student{name='张三', age=23}
反射获取父类/父接口
import java.lang.reflect.AnnotatedType; /** * @author zhangzhixi * @date 2021-5-5 10:03 */ public class Test06_获取类的父类_父接口 { public static void main(String[] args) throws Exception { Class<?> aClass = Class.forName("java.lang.String"); // 获取父类 Class<?> superclass = aClass.getSuperclass(); System.out.println(superclass); System.out.println("==============="); // 获取父接口 Class<?>[] interfaces = aClass.getInterfaces(); for (Class<?> anInterface : interfaces) { System.out.println(anInterface); } } }
测试结果:
class java.lang.Object =============== interface java.io.Serializable interface java.lang.Comparable interface java.lang.CharSequence