java的反射

反射的概述

Java的反射机制:是指在运行去获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用再编译期就完成确定,在运行期仍然可以扩展。

通过反射获取到构造方法:

先说只能获取到一个构造方法的方法:

Class c=Class.forName("Reflect.Student");//引号中的为学生类的路径

Constructor con=c.getConstructor();//获取无参构造方法

Student s=(Student)con.getInstance();

下面的和上面的相同(这里说明在调用反射时需要抛出异常)

public static void method01(String addr){
        //构造方法通过反射来调用
        try{
            //字节码,代表Student类在内存中的字节码对象
            Class clazz=Class.forName(addr);
            Constructor cs = clazz.getConstructor();//获取到构造方法->无参构造方法
            //cs.newInstance();//通过无参构造创建对象
            Student s=(Student) cs.newInstance();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

下面来进行扩展

获取构造方法处:

(1).Constructor con=c.getConstructor(String.class,int.class);//这里是有参构造方法

           Student s=(Student) con.newInstance("李四",28);//使用构造方法进行赋值

(2).Constructor con=c.getConstructor(int.class);

           Student s=(Student) con.newInstance(28);//使用构造方法进行赋值

系统会根据参数的个数自动去获取是哪个构造方法,以上几种只能获取到共有的构造方法。

下面进行私有的构造方法的获取:

Constructor con=c.getDeclaredConstructor();

con.setAccessible(true);

Constructor con=c.getDeclaredConstructor(String.class,int.class);

con.setAccessible(true);//在获取私有的构造方法时,需要调用该方法,取消访问检查,也叫作暴力反射

Student s=(Student) con.newInstance("李四",28);//使用构造方法进行赋值

 下面来介绍可以获取全部的构造方法的方法:

Class c=Class.forName("Reflect.Student");//引号中的为学生类的路径

Constructor[ ] con=c.getConstructors();//注意这里加了s,该方法可以获取所有的公有属性的构造方法

Constructor[ ] con=c.getDeclaredConstructors();//该方法可以获取到所有的构造方法(包括私有的构造方法)

 以下时代码实现

private static void method01() {
        try{
            Class c=Class.forName("Reflect.Student");
            //获取字节码中共有化的构造方法
            Constructor[] con = c.getConstructors();
            for (Constructor co:con) {
                System.out.println(co);
            }
            //获取所有的构造方法
            Constructor[] caAll=c.getDeclaredConstructors();
            for (Constructor co1:caAll) {
                System.out.println(co1);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

通过反射来获取成员方法:

先时获取一个成员方法的方法,并且只能获取到一个方法(而且还是共有的成员方法):

Class c=Class.forName("Reflect.Student");

Student s=c.getInstance();//获取无参构造方法

Method m=c.getMethod("getName",String.class);//引号中为需要调用的方法名,后面的为参数,没有就不写

Method m=c.getMethod("getName");

m.invoke(s,"李四");//s为创建的学生对象,李四为传进去的参数,没有同样不写

m.invoke(s);//理解为对象s调用方法m,方法m反射给对象

public static void method05(String addr){
        try{
            Class clazz=Class.forName(addr);
            //通过无参构造方法创建对象
            Student s=(Student) clazz.newInstance();
            //通过方法名及参数列表获取对应的方法
            Method m=clazz.getMethod("setBirthday",Date.class);
            m.invoke(s,new Date());//方法的调用
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void method06(String addr){
        try{
            Class clazz=Class.forName(addr);
            //通过无参构造方法创建对象
            Student s=(Student) clazz.newInstance();
            //通过方法名及参数列表获取对应的方法
            Method m=clazz.getMethod("addStuNames",String[].class);
            //m.setAccessible(true);
            m.invoke(s,(Object) new String[]{"123","hqj","lsj"});//方法的调用
        }catch (Exception e){
            e.printStackTrace();
        }
    }

接下来能获取到私有的成员方法:

Class c=Class.forName("Reflect.Student");

Student s=(Student)c.getInstance();

Method m=c.getDeclaredMethod("getName");

m.setAccessible();

m.invoke(s);

//如果方法中有参数

Method m=c.getDeclaredMethod("getName",String.calss);

m.setAccessible();

m.invoke(s,"李四");

 

private static void method03(String addr) {
        try{
            Class clazz=Class.forName(addr);
            //通过无参构造方法创建对象
            Student s=(Student) clazz.newInstance();
            //通过方法名及参数列表获取对应的方法
            Method m=clazz.getMethod("getName");
            String name=(String) m.invoke(s);//方法的调用
            System.out.println("返回的值:"+name);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private static void method04(String addr) {
        try{
            Class clazz=Class.forName(addr);
            //通过无参构造方法创建对象
            Student s=(Student) clazz.newInstance();
            //通过方法名及参数列表获取对应的方法
            Method m=clazz.getDeclaredMethod("youName");
            m.setAccessible(true);//值为true是取消访问检查
            m.invoke(s);//方法的调用
            //System.out.println("返回的值:"+name);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

接下来介绍获取全部方法的方法:

private static void method02() {
        try{
            Class c=Class.forName("Reflect20210629.Student");
            System.out.println("........公有化.......");
            Method ms[]=c.getMethods();
            for (Method m:ms) {
                System.out.println(m);
            }
            System.out.println("所有方法不含继承的方法");
            Method msAll[]=c.getDeclaredMethods();
            for (Method s:msAll){
                System.out.println(s);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

通过反射来获取成员变量:

方法与获取成员方法相同,此处就不作解释,直接放代码例子:

先是获取单个成员变量的:method01只能获取到公有成员,method02能获取公有和私有的成员

private static void method01(String addr) {
        try{
            Class clazz=Class.forName(addr);
            Student s=(Student)clazz.newInstance();
            //获取属性
            Field f=clazz.getField("age");
            //set值
            f.set(s,20);
            //s.age=40;
            //get值
            int age=(int)f.get(s);
            System.out.println(age);
            //age=s.age;
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private static void method02(String addr) {
        try{
            Class clazz=Class.forName(addr);
            Student s=(Student)clazz.newInstance();
            //获取属性
            Field f=clazz.getDeclaredField("name");
            f.setAccessible(true);
            //set值
            f.set(s,"yjw1123");
            //s.age=40;
            //get值
            String name=(String) f.get(s);
            System.out.println(name);
            //age=s.age;
        }catch (Exception e){
            e.printStackTrace();
        }
    }

获取全部变量的:

private static void method03() {
        try{
            Class c=Class.forName("Reflect20210629.Student");
            System.out.println(">>>>>>>>>>>公有属性>>>>>>>>>");
            Field[] fs=c.getFields();
            for (Field f:fs) {
                System.out.println(f);
            }
            System.out.println("...........所有属性..........");
            Field fsAll[]=c.getDeclaredFields();
            for (Field f:fsAll) {
                System.out.println(f);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值