【JAVA】反射

目录

一、获取class对象的三种方法

二、利用反射获取构造方法

获取构造方法

创建对象

获取修饰符

获取参数

三、利用反射获取成员变量

获取成员变量

四、利用反射获取成员方法


什么是反射

反射允许对封装类的字段,方法和构造函数的信息进行编程访问,即

反射允许对成员变量,成员方法和构造方法的信息进行编程访问

首先要先获取class字节码对象,在根据这个对象获取字段对象(Field)、构造对象(Constructor)、方法对象(Method)

反射的作用:

1、获取一个类里面所有的信息,获取到了之后,在执行其他的业务逻辑

2、结合配置文件,动态的创建对象并调用方法

一、获取class对象的三种方法

1、Class.forName("全类名");使用场景:源代码阶段

全类名=包名+类名

获取全类名的方式:选中类名,右键单击,选择Copy-----Copy Reference

2、类名.class; 加载阶段

3、对象.getClass(); 运行阶段

public static void main(String[] args) throws ClassNotFoundException {
        //1、第一种方式
        //最为常用
        Class clazz1 = Class.forName("exam.Student");
        
        //2、第二种方式
        //一般更多的是当做参数进行传递
        Class clazz2 = Student.class;
        
        //3、第三种方式
        //当已经有了这个类的对象时,才可以使用
        Student s = new Student();
        Class clazz3 = s.getClass();
        
    }

二、利用反射获取构造方法

获取构造方法

Class类中用于获取构造方法的方法

Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组

Constructor<?>[] getDeclaredConstructor():返回所有构造方法对象的数组

Constructor<T> getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象

package exam;
​
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
​
public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //1、获取class字节码文件对象
        Class clazz1 = Class.forName("exam.Student");
        //2、获取构造方法
        //获取所有公共构造方法
        Constructor[] cons1 = clazz1.getConstructors();
        for(Constructor con : cons1){
            System.out.println(con);
        }
        System.out.println("-----------------");
        //获取所有构造方法(包括私有、受保护的)
        Constructor[] cons2 = clazz1.getDeclaredConstructors();
        for (Constructor constructor : cons2) {
            System.out.println(constructor);
        }
​
        System.out.println("-------------------");
        //获取单个公共构造方法
        //获取无参构造方法
        Constructor con = clazz1.getConstructor();
        System.out.println(con);
​
        System.out.println("-------------------");
        //获取带参的公共构造方法
        Constructor constructor = clazz1.getConstructor(String.class,int.class,String.class,String.class);
        System.out.println(constructor);
​
        //获取单个构造方法
        Constructor constructor1 = clazz1.getDeclaredConstructor(String.class);
        System.out.println("---------------");
        System.out.println(constructor1);
​
        //获取构造方法的权限修饰符,返回的是修饰符对应的数字
        int modifiers = constructor1.getModifiers();
        System.out.println(modifiers);
​
        //获取构造方法的参数
        Parameter[] parameters = constructor1.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
​
        //创建对象
        Student stu = null;
        try {
            stu = (Student) constructor.newInstance("张三",22,"202001","软件工程");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(stu);
    }
}
创建对象

Constructor类中用于创建对象的方法

注意:

如果是私有的构造方法,需要在创建对象前,使用setAccessible(true)临时取消访问权限检测。

T newlnstance(Object...initargs):根据指定的构造方法创建对象
setAccessible(boolean flag):设置为true,表示取消访问检查
获取修饰符

获取构造方法的权限修饰符,返回的是修饰符对应的整数

//获取构造方法的权限修饰符,返回的是修饰符对应的数字
int modifiers = constructor1.getModifiers();
System.out.println(modifiers);

获取参数
//获取构造方法的参数
Parameter[] parameters = constructor1.getParameters();
for (Parameter parameter : parameters) {
    System.out.println(parameter);
}

三、利用反射获取成员变量

获取成员变量

Class类中用于获取成员变量的方法

Field[] getFields():返回所有公共成员变量对象数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象

用法和上面构造方法一样

Field类中用于创建对象的方法

void set(Object obj,Object value):赋值
Object get(Object obj):获取值


package exam;
​
import java.lang.reflect.Field;
​
public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException,  NoSuchFieldException {
        //1、获取class字节码文件对象
        Class clazz1 = Class.forName("exam.Student");
​
        //获取所有公共成员变量
        Field[] fields = clazz1.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
​
        //获取单个成员变量
        Field majorField = clazz1.getDeclaredField("major");
        System.out.println(majorField);
        //获取权限修饰符
        int modifiers = majorField.getModifiers();
        System.out.println(modifiers);
        //获取成员变量类型
        Class type = majorField.getType();
        System.out.println(type);
​
        //获取成员变量的值
        Student stu = new Student("李四",18,"202001","大数据");
        try {
            //由于major是用private修饰的,所以想要查看值,则需要暴力反射
            majorField.setAccessible(true);
            Object value = majorField.get(stu);
            System.out.println(value);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
​
        //修改成员变量的值
        try {
            majorField.set(stu,"人工智能");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println(stu);
    }
}

四、利用反射获取成员方法

Class类中用于获取成员便方法的方法

Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象数组,不包括继承的
Method getMethod(String name,Class<?>...parameterTypes):返回单个公共成员方法对像。第一个参数是方法的名字,后面的参数是方法的参数
Method getDeclaredMethod(String name,Class<?>...parameterTypes):返回单个成员方法对象

成员方法也有修饰符和参数等,都和构造方法的获取方式一样

Mehod类中用于创建对象的方法

Object invoke(Object obj,Object...args):运行方法

参数一:用obj对象调用该方法

参数二:调用方法的传递的参数(如果没有就不写)

返回值:方法的返回值(如果没有就不写)

package exam;
​
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
​
public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException,  NoSuchFieldException {
        //1、获取class字节码文件对象
        Class clazz1 = Class.forName("exam.Student");
​
        //获取所有公共方法,包括继承来的
        Method[] methods = clazz1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("------------");
        //获取所有方法对象,不包括继承的,但包括私有的等
        Method[] methods1 = clazz1.getDeclaredMethods();
        for (Method method : methods1) {
            System.out.println(method);
        }
        System.out.println("------------");
        //获取单个方法
        Method method = null;
        try {
            method = clazz1.getMethod("eat",String.class);
            System.out.println(method);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //获取方法的抛出的异常
        Class[] exceptionTypes = method.getExceptionTypes();
        //方法运行
        Student stu = new Student("王麻子",21,"202001","大数据");
        try {
            method.invoke(stu,"橙子");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值