Java【反射机制】概述

1. 反射

反射是指对于任何一个Class类,在“运行的时候,都可以直接得到这个类的全部成分”。在运行时可以得到类的构造器对象,成员变量对象,成员方法对象。这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言反射机制。在这里插入图片描述
反射在运行时获取类的字节码文件对象,然后可以解析类中的全部成分。反射的核心思想和关键就是:得到编译后的class文件对象。

2. 步骤

2.1 获取Class类对象

在这里插入图片描述

public class Test {
    public static void main(String[] args) throws Exception{
        //1、Class类中的一个静态方法:forName
        Class c  = Class.forName("com.qjz.reflectclass.Student");
        System.out.println(c);

        //2、类名.class
        Class c1 = Student.class;
        System.out.println(c1);

        //3、对象.getClass();
        Class c2 = new Student().getClass();
        System.out.println(c2);
    }
}

2.2 反射获取构造器

通过反射技术获取构造器,构造器还是用来创建对象的,如果是非public的构造器,需要打开权限进行暴力反射,然后再创建对象。

    /**
     * 通过类类型对象获取构造函数,注意共有私有的问题
     */
    @Test
    public void getConstructor() throws Exception {
        Class c = Student.class;
        //获取一个指定的,私有的,带参的构造器
        Constructor cons = c.getDeclaredConstructor(String.class, int.class);
        //Constructor constructor = c.getConstructor();获取一个共有的无参构造函数。

        //打印构造函数对象属于的类,及构造函数需要的参数个数
        System.out.println(cons.getName() + "====>" + cons.getParameterCount());

        //通过构造器创建对象
        //非public的构造器,需要打开暴力反射开关
        cons.setAccessible(true);
        Student s = (Student) cons.newInstance("孙行者",1001);
        System.out.println(s);
    }

2.3 反射获取成员变量

反射第一步得到类对象,然后从类对象中获取类的成分对象。

    /**
     * 通过反射获取对象成员变量
     */
    @Test
    public void getDeclareFields() throws Exception {
        Class c = Student.class;

        //拿到全部的成员变量
        Field[] fields = c.getDeclaredFields();
        for (Field f : fields) {
            System.out.println(f.getName() + "的类型为:" + f.getType());
        }

        //拿到某个成员变量
        Field f = c.getDeclaredField("name");
        System.out.println(f.getName() + "的类型为:" + f.getType());

        //为"名字"成员变量赋值
        Student s = new Student();//要为名字对象赋值需现有学生对象
        f.setAccessible(true);//该变量为私有变量需要开启暴力反射
        f.set(s, "孙行者");
        System.out.println(s);

        //f是学生类的,成员变量对象中的,名字对象;
        //名字对象要取值,就得交代是哪个学生对象中的“值,这里的对象为s,
        //这个值是名字对象取的,所以取到名字成员变量值(总不能让 名字 去取 编号吧)
        String name = (String) f.get(s);
        System.out.println(name);
    }

2.3 反射获取方法对象

	    /**
     * 反射获取方法,然后调用
     * @throws Exception
     */
    @Test
    public void getMethod() throws Exception {
        Class c = Student.class;

        //通过名字和参数类型确定要拿的是哪个方法。
        Method m1 = c.getDeclaredMethod("studentOtherAction");
        Method m2 = c.getMethod("studenAcction", int.class);
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName()+"的返回值类型为:"+method.getReturnType());
        }

        //触发方法的执行
        Student s = new Student();
        //暴力反射
        m1.setAccessible(true);
        m1.invoke(s);
        //用一个变量接返回结果
        Object result = m2.invoke(s,1);
        System.out.println(result);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值