Java反射基础

    xiaoxiao2025-08-15  2

    Reflection(反射)是Java被视为动态语言(动态语言:程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。

    一句话概括:反射就是把Java类中的各种成分映射成一个个的Java对象

    简单画了个图,凑合看吧,自己的理解,如有大神希望多多指教

    首先创建一个Student类,为了后面操作方便,在类里面分别创建了四种不同访问权限的构造函数,成员变量以及成员方法

    package com.example.testdemo.classforname; public class Student { //构造方法 public Student() { System.out.println("(公有)的构造器被执行了---------"); } public Student(String name, int age) { this.age = age; this.name = name; System.out.println("(公有带参)的构造器被执行了---------"); } Student(String name) { this.name = name; System.out.println("(默认)的构造器被执行了---------"); } private Student(int age) { this.age = age; System.out.println("(私有)的构造器被执行了---------"); } protected Student(double grade) { this.grade = grade; System.out.println("(受保护)的构造器被执行了---------"); } //成员变量 String name; private int age; public double grade; public int classNumber; protected String sex; //成员函数 void method1(String name) { System.out.println("(默认)的方法被执行了---------"); } public void method2() { System.out.println("(公有)的方法被执行了---------"); } private void method3(double grade) { System.out.println("(私有)的方法被执行了---------"); } protected void method4(String sex) { System.out.println("(受保护)的方法被执行了---------"); } @Override public String toString() { return "[name:" + name + ",age:" + age + ",grade:" + grade + ",sex:" + sex + ",classNumber:" + classNumber + "]"; } public static void main(String[] args) { System.out.println("main方法被执行" + args.toString()); } }

    反射的使用在这里大致分为四个部分:

    获取class对象

    获取class对象有三种方式

    package com.example.testdemo.classforname; /** * 获取class对象 */ public class Test { public static void main(String[] args) throws Exception { //获取class文件的三种方法: //1,根据对象获取class(无意义)已经有对象 Student student = new Student(); Class clazz = student.getClass(); //2,根据对象.class(无意义)一般需要导入类的相关包 clazz = Student.class; //3,根据类名获取class(推荐使用) clazz = Class.forName("com.example.testdemo.classforname.Student"); System.out.println(clazz); //class对象获取实例对象 Object object= clazz.newInstance(); System.out.println(object); } }

    获取构造函数

    package com.example.testdemo.classforname; import java.lang.reflect.Constructor; /** * 获取class对象的构造函数 */ public class Test1 { public static void main(String[] args) throws Exception { //获取class对象 Class clazz = Class.forName("com.example.testdemo.classforname.Student"); //分为两组 //第一组:1,获取单个(公有)构造函数 System.out.println("获取单个(公有)构造函数---------"); Constructor constructor = clazz.getConstructor(); System.out.println(constructor); constructor = clazz.getConstructor(String.class, int.class);//获取有参构造需要传入参数类型 System.out.println(constructor); //第一组:2,获取单个(所有包括公有的,私有的,默认的,受保护的)构造函数 System.out.println("获取单个(所有包括公有的,私有的,默认的,受保护的)构造函数---------"); constructor = clazz.getDeclaredConstructor(String.class);//获取有参构造需要传入参数类型 System.out.println(constructor); //根据不同构造器创建实例对象 Object obj = constructor.newInstance("张三"); System.out.println(obj); //第二组:1,获取多个(公有)构造函数 System.out.println("获取多个(公有)构造函数---------"); Constructor[] constructors = clazz.getConstructors(); for (Constructor c : constructors) { System.out.println(c); } //第二组:2,获取多个(所有包括公有的,私有的,默认的,受保护的)构造函数 System.out.println("获取多个(所有包括公有的,私有的,默认的,受保护的)构造函数---------"); constructors = clazz.getDeclaredConstructors(); for (Constructor c : constructors) { System.out.println(c); } } }

     

    获取成员变量

    package com.example.testdemo.classforname; import java.lang.reflect.Field; /** * 获取class对象的成员变量 */ public class Test2 { public static void main(String[] args) throws Exception { //获取class对象 Class clazz = Class.forName("com.example.testdemo.classforname.Student"); //分为两组 //第一组:1,获取单个(公有)成员变量 System.out.println("获取单个(公有)成员变量---------"); Field field = clazz.getField("grade");//需要传入成员变量名称 System.out.println(field); //第一组:2,获取单个(所有包括公有的,私有的,默认的,受保护的)成员变量 System.out.println("获取单个(所有包括公有的,私有的,默认的,受保护的)成员变量---------"); field = clazz.getDeclaredField("age");//需要传入成员变量名称 System.out.println(field); //获取私有属性并赋值 Object obj = clazz.newInstance(); //age是私有属性,需要暴力设置 field.setAccessible(true); field.set(obj,15); System.out.println(obj); //第二组:1,获取多个(公有)成员变量 System.out.println("获取多个(公有)成员变量---------"); Field[] fields = clazz.getFields(); for (Field f : fields) { System.out.println(f); } //第二组:2,获取多个(所有包括公有的,私有的,默认的,受保护的)成员变量 System.out.println("获取多个(所有包括公有的,私有的,默认的,受保护的)成员变量---------"); fields = clazz.getDeclaredFields(); for (Field f : fields) { System.out.println(f); } } }

     

    获取成员方法

    package com.example.testdemo.classforname; import java.lang.reflect.Method; /** * 获取成员方法 */ public class Test3 { public static void main(String[] args) throws Exception { //获取class对象 Class clazz = Class.forName("com.example.testdemo.classforname.Student"); //分为两组 //第一组:1,获取单个(公有)成员方法 System.out.println("获取单个(公有)成员方法---------"); Method m = clazz.getMethod("method2");//需要传入成员方法名称,有参数需要传入参数 System.out.println(m); //第一组:2,获取单个(所有包括公有的,私有的,默认的,受保护的)成员方法 System.out.println("获取单个(所有包括公有的,私有的,默认的,受保护的)成员变量---------"); m = clazz.getDeclaredMethod("method3",double.class);//需要传入成员方法名称 System.out.println(m); //获取方法后执行 Object obj = clazz.newInstance(); //method3是私有方法需要暴力设置 m.setAccessible(true); m.invoke(obj,89.50);//传入方法需要的参数 //第二组:1,获取多个(公有)成员方法 System.out.println("获取多个(公有)成员方法--------"); Method[] methods = clazz.getMethods(); for (Method m1 : methods) { System.out.println(m1); } //第二组:2,获取多个(所有包括公有的,私有的,默认的,受保护的)成员方法 System.out.println("获取多个(所有包括公有的,私有的,默认的,受保护的)成员方法---------"); methods = clazz.getDeclaredMethods(); for (Method m1 : methods) { System.out.println(m1); } } }

    突发奇想能不能获取类中的main方法?不说了,直接上代码测试

    package com.example.testdemo.classforname; import java.lang.reflect.Method; /** * 获取class中的main方法 */ public class Test4 { public static void main(String[] args) throws Exception { //获取class对象 Class clazz = Class.forName("com.example.testdemo.classforname.Student"); //main方法是公有方法 Method method = clazz.getMethod("main",String[].class); //main方法没有对象(静态方法),需要注意invoke传入的参数是object类型必须强转,不然出现异常 method.invoke(null,(Object) new String[]{"aaaaa"}); } }

    依然是可以拿到的,以前觉得反射没有什么用,除了在jdbc的时候使用,最近看了一些框架,基本都是反射,编程的路漫漫,我们一起走吧

    最新回复(0)