反射的使用:基础全面讲解

本文介绍了Java中的反射机制,包括通过三种方式获取类对象,以及使用反射操作类的属性、构造方法和普通方法。详细讲解了如何获取和操作Field、Constructor和Method,包括对私有成员的访问,并通过示例代码展示了反射的应用。
摘要由CSDN通过智能技术生成

目录

概念:

获取类对象(三种方式)

反射三部曲:

获取类中的属性: Field

获取构造方法 Constructor

获取普通方法 Method


概念:

       首先,我们要认识下反射是用来干什么的,目前而言,我所认知,反射即是通过获取类对象,来间接获取类中的属性、构造方法、普通方法,来对其间接操作

这里需注意类对象与类的对象的区别:

       类对象是唯一的;

       类的对象是可以有多个的,也就是实例化对象

获取类对象(三种方式)

@Test
public void test_01() throws ClassNotFoundException {
    // 方式一:通过类的对象获取类对象
    // 实例化一个学生对象
    Student stu = new Student();
    Class aClass = stu.getClass();
    
    // 方式二:通过类.class获取
    Class bClass = Student.class;
    
    // 方式三:通过Class.forName(全限定包名)   注意:全限定包名要定位到类名上,也就是引用的类的包名全称
    Class cClass = Class.forName("com.school.data02.study04.Student");
}

        那么,类对象获取到了,又能做什么呢?接下来就是用类对象来实施对类中的属性、构造方法、普通方法进行获取操作,我们一般称之为“反射”

反射三部曲:

获取类中的属性: Field

@Test
public void test_03() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
    // 1、获取类对象   							一般使用方式三来获取哈,较为实用
    Class cls = Class.forName("com.school.data02.study04.Student");
    // 2、先来获取指定的公开的属性   				这里返回值用Field类来接收
    Field field = cls.getField("name");
    // 注意:这里对属性进行赋值前,我们需要提供一个对象,为其对象的该属性赋值,不然,你还想给属性赋默认值啊!
    // 实例化一个类的对象     					这里默认Object接收哈,别酱
    Object obj = cls.newInstance();
    // 3、对属性进行赋值        					注意: 我这里name属性为String型,什么型赋什么值
    field.set(obj,"木子");
    // 4、获取属性中的值    
    // 这里可能容易混哈, 要记住field是属性名,  以此来获取这个对象的属性值
    Object name = field.get(obj);   			 // 返回值还是用Object接收
    System.out.println(name);
    
    // 5、获取所有公开的属性(包括父类的)
    Field[] fields = cls.getFields();
    //  数组流输出查看,不懂就用for遍历查看
    Arrays.stream(fields).forEach(System.out::println);   
    // 6、获取指定的私有属性,使用方式都差不多
    Field f = cls.getDeclaredField("age");
    // System.out.println(f.getName());
    // 私有属性进行赋值时,需要进行暴力反射,不然会报错
    f.setAccessible(true);                      // 即:暴力反射,也就是打开某个开关而已,不用太理解
    f.set(obj,12);   // 赋值
    System.out.println(obj);
    // 7、获取所有的属性(包括私有的)
    Field[] f_s = cls.getDeclaredFields();
    Arrays.stream(f_s).forEach(System.out::println);
}

获取构造方法 Constructor

@Test
public void test_04() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //1、获取类对象
        Class cls = Class.forName("com.school.data02.study04.Student");
        //获取这个类的指定的构造方法         		     有参则需要带上参数 类型.class形式
        Constructor constructor = cls.getConstructor(String.class,String.class,int.class);
        System.out.println(constructor);
        //通过构造方法new对象                          必须对应上方构造的参数的类型及个数
        Object obj = constructor.newInstance("001","jack",23);
        System.out.println(obj);
        System.out.println("-------------");
        //获取所有公开的构造方法
        Constructor[] constructors = cls.getConstructors();
        Arrays.stream(constructors).forEach(System.out::println);    // 遍历输出
        System.out.println("--------------");
        //获取所有的构造方法(包括私有的)
        Constructor[] constructors_s = cls.getDeclaredConstructors();
        Arrays.stream(constructors_s).forEach(System.out::println);
        System.out.println("---------------");
        //获取指定私有的有参构造方法
        Constructor constructor_s = cls.getDeclaredConstructor(String.class,int.class);
        System.out.println(constructor_s);
        //设置私有可以访问(暴力反射)
        constructor_s.setAccessible(true);     		  // 私有需要暴力反射
        Object obj_s = constructor_s.newInstance("彩虹",23);
        System.out.println(obj_s);
}

获取普通方法 Method

@Test
public void test_05() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //获取类对象
        Class cls = Class.forName("com.school.data02.study04.Student");
        Object obj = cls.newInstance();
        //获取指定公开的方法
        Method method = cls.getMethod("method", String.class);
        System.out.println(method.getName());
        //利用反射调用方法,并接收返回值     方法的调用 .invoke()的新使用  有参则传参
        Object result = method.invoke(obj,"jack");
        System.out.println(result);
        System.out.println("----------------------");
        //获取所有的公开的方法(包括父类的公开的方法)
        Method[] methods = cls.getMethods();
        Arrays.stream(methods).forEach(System.out::println);
        System.out.println("-----------------------");
        //获取指定的私有方法
        Method method_s = cls.getDeclaredMethod("s_method", String.class);
        System.out.println(method_s);
        //利用反射调用私有方法,并接收返回值(如果方法没有返回值。那么invoke方法就返回null)
        method_s.setAccessible(true);                            // 暴力反射
        Object s_result = method_s.invoke(obj,"Mark");
        System.out.println(s_result);
        System.out.println("------------------");
        //获取本类中所有的方法(包括私有的)
        Method[] methods_s = cls.getDeclaredMethods();
        Arrays.stream(methods_s).forEach(System.out::println);
}

总结:

以上即为反射的基本内容,这里只是简单认识下反射的使用方式,谢谢您的耐心阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值