Java反射机制:通过反射机制获取类的成员(构造方法,成员变量,成员方法);通过反射越过泛型检查;通过反射运行配置文件内容

it2025-06-16  9

文章目录

Java反射机制一、反射机制概述二、获取class文件对象的三种方式三、通过反射获取构造方法并使用四、通过反射获取成员变量并使用五、通过反射获取成员方法并使用六、通过反射越过泛型检查七、通过反射运行配置文件内容

Java反射机制

一、反射机制概述

反射概述: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性; 这种动态获取类的信息以及动态调用对象的方法的功能称为Java语言的反射机制。 要想解剖一个类,必须先要获取到该类的字节码文件对应的Class类型的对象,因为解剖使用的是Class类中的方法。 类的成员: 成员变量 Field 构造方法 Constructor 成员方法 Method

二、获取class文件对象的三种方式

a:Object类的getClass()方法 b:静态属性class c:Class类中静态方法forName() public class MyTest { public static void main(String[] args) throws ClassNotFoundException { //Object类的getClass()方法 Class<? extends MyTest> aClass = new MyTest().getClass(); // 静态属性class Class<MyTest> myTestClass = MyTest.class; //Class类中静态方法forName(),参数为全类名 Class<?> aClass1 = Class.forName("mydemo.MyTest"); //class文件对象只有一个,所以无论通过何种方式获取的class文件对象都是同一个 System.out.println(myTestClass==aClass&&aClass==aClass1);//true } }

三、通过反射获取构造方法并使用

//获取所有公共的构造方法的对象数组 public Constructor<?>[] getConstructors() //获取所有的构造方法(包括私有的)的对象数组 public Constructor<?>[] getDeclaredConstructors() //获取单个公共构造方法的对象 public Constructor<T> getConstructor(Class<?>... parameterTypes) //获取单个构造方法的对象,包含私有的 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) T newInstance() //创建此 Class 对象所表示的类的一个新实例 public void setAccessible(boolean flag)//AccessibleObject的方法 //将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。 import java.lang.reflect.Constructor; public class MyTest { public static void main(String[] args) throws Exception { Class<?> aClass = Class.forName("mydemo1.Student"); //获取所有公共的构造方法的对象数组 Constructor<?>[] constructors = aClass.getConstructors(); //获取所有的构造方法(包括私有的)的对象数组 Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors(); //获取单个私有构造方法的对象 Constructor<?> constructor = aClass.getDeclaredConstructor(); //取消访问检查 constructor.setAccessible(true); //通过私有构造方法对象创建Student对象 Student student = (Student) constructor.newInstance(); System.out.println(student); System.out.println("--------------------------------"); //获取公共有参构造方法对象 Constructor<?> constructor1 = aClass.getConstructor(String.class, int.class); Student student1 = (Student) constructor1.newInstance("张三", 23); System.out.println(student1); } } class Student { private Student() { System.out.println("私有空参构造执行了"); } public Student(String name,int age) { System.out.println("有参构造执行了,"+name+"=="+age); } }

运行结果:

私有空参构造执行了 mydemo1.Student@4554617c -------------------------------- 有参构造执行了,张三==23 mydemo1.Student@74a14482 Process finished with exit code 0

四、通过反射获取成员变量并使用

//获取所有公共成员变量的对象,包含从父类继承过来的 public Field[] getFields() //获取所有成员变量的对象,包含私有的,也包含从父类继承过来的 public Field[] getDeclaredFields() public Field getField(String name)//获取单个公共成员变量的对象 public Field getDeclaredField(String name)//获取单个成员变量的对象 import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class MyTest { public static void main(String[] args) throws Exception{ //创建Student对象 Class<?> aClass = Class.forName("mydemo2.Student"); Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(); declaredConstructor.setAccessible(true); Object stu = declaredConstructor.newInstance(); //获取成员变量对象,并给成员变量赋值 Field name = aClass.getField("name");//参数为字段名称 name.set(stu,"张三");//参1为字段所属对象,参2为要赋的值 Field age = aClass.getDeclaredField("age"); age.set(stu,23); Field x = aClass.getDeclaredField("x"); x.setAccessible(true);//取消访问检查 x.set(stu,3.323); System.out.println(name.get(stu)+"=="+age.get(stu)+"=="+x.get(stu)); //张三==23==3.323 } } class Student{ public String name; int age; private double x; private Student(){} }

五、通过反射获取成员方法并使用

//获取所有公共成员方法的对象数组,包含从父类继承过来的公共方法 public Method[] getMethods() public Method[] getDeclaredMethods()//获取自己所有成员方法的对象数组 //获取单个公共成员方法的对象 public Method getMethod(String name,Class<?>... parameterTypes) //获取单个成员方法的对象,包括私有的 public Method getDeclaredMethod(String name,Class<?>... parameterTypes) //参数1: 方法名称 参数2:方法行参的class 对象 import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class MyTest { public static void main(String[] args)throws Exception{ //创建MyClass对象 Class<?> aClass = Class.forName("mydemo3.MyClass"); Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(); declaredConstructor.setAccessible(true); Object o = declaredConstructor.newInstance(); //获取单个公共成员方法的对象 Method show = aClass.getMethod("show"); show.invoke(o);//执行此方法,参数为此方法所属对象 //获取私有的成员方法对象 Method show1 = aClass.getDeclaredMethod("show", int.class); show1.setAccessible(true);//取消权限检查 Object invoke = show1.invoke(o, 22); System.out.println(invoke);//返回值 Method haha = aClass.getDeclaredMethod("test", String.class, int.class); haha.setAccessible(true); Object invoke1 = haha.invoke(o, "我是", 777); System.out.println(invoke1); } } class MyClass{ private MyClass() { System.out.println("私有构造方法执行了"); } public void show(){ System.out.println("无参公共的show方法执行了"); } private String show(int num){ System.out.println("有参私有的show方法执行了"); return "show:"+num; } private String test(String str,int num){ System.out.println("有参私有的test方法执行了"); return "test:"+str+num; } }

运行结果:

私有构造方法执行了 无参公共的show方法执行了 有参私有的show方法执行了 show:22 有参私有的test方法执行了 test:我是777 Process finished with exit code 0

六、通过反射越过泛型检查

//往ArrayList<Integer>里添加String类型元素 //原理:泛型只在编译期有效,运行期就会擦除,而反射机制是在运行状态中 import java.lang.reflect.Method; import java.util.ArrayList; public class MyTest { public static void main(String[] args) throws Exception{ ArrayList<Integer> list = new ArrayList<>(); list.add(100); Class<? extends ArrayList> aClass = list.getClass(); Method add = aClass.getDeclaredMethod("add", Object.class); add.setAccessible(true); add.invoke(list,"abc"); System.out.println(list);//[100, abc] } }

七、通过反射运行配置文件内容

import java.io.FileReader; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Properties; public class MyTest1 { public static void main(String[] args) throws Exception { //要使用某个类的某个方法,只需要修改配置文件即可 Properties properties = new Properties(); //关联配置文件 properties.load(new FileReader("configurationFile.properties")); //获取配置文件中指定类的Class对象 Class<?> aClass = Class.forName((String) properties.get("className")); //获取构造方法对象 Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(); declaredConstructor.setAccessible(true);//取消安全检查 //创建配置文件中指定类的对象 Object o = declaredConstructor.newInstance(); //获取配置文件中指定方法的对象 Method mathod = aClass.getDeclaredMethod((String) properties.get("mathodName")); //取消安全检查 mathod.setAccessible(true); mathod.invoke(o);//执行方法 } } class Dog { private Dog() { } public void eat() { System.out.println("狗吃骨头"); } public void sleep() { System.out.println("狗晚上睡觉"); } } class Cat { private Cat() { } public void eat() { System.out.println("猫吃鱼"); } public void sleep() { System.out.println("猫白天睡觉"); } } 配置文件内容: className=mydemo4.Dog mathodName=sleep 对应运行结果: 狗晚上睡觉 配置文件内容: className=mydemo4.Cat mathodName=eat 对应运行结果: 猫吃鱼
最新回复(0)