反射机制的使用

4 篇文章 0 订阅

学习了反射机制之后,在这里总结一下如何使用,以顾自己复习。

与反射相关的几个类:

Java.lang.Class;//Class类

Java.lang.reflect.Constructor;//构造方法类

Java.lang.reflect.Field;//对象中的属性类

Java.lang.reflect.Method;//对象中的方法类

Java.lang.reflect.Modifier;//属性/方法的修饰符

目录

获取Class的三种方法:

获取类的属性:

修改属性的值:

通过反射机制获取方法以及调用方法:

使用构造方法创建对象

通过反射获取父类以及实现的接口


获取Class的三种方法:

  1. 数据类型.class,如int.class,String.class,任何数据类型都有.class,可以直接调用
  2. 对象.getClass(),如String str=new Stirng(); Class c=str.getClass();
  3. Class.forName("完整类名")
            //第一种
            Class string = Class.forName("java.lang.String");
            //第二种
            String str="abc";
            Class aClass = str.getClass();
            //第三种
            Class stringClass = String.class;

获取类的属性:

  1.    先获取整个类的class
  2. 由类得到Field数组,因为属性可能有多个,所以返回值是数组。Fleld[] fields=cls.getDeclaredFields();
  3. 一个Field包括修饰符、数据类型、字段名。
  4. 获取字段名的方法是:fs.getName();
  5. 获取字段名类型的方法是:fs.getType();
  6. 获取字段名修饰符的方法是:fs.getModifiers();//返回值是修饰符的字符串,所以使用Modifier.toString()转化为修饰符

 

        Field[] stuFileds = fileds.getDeclaredFields();
        for (Field fs:fileds){
            //获取字段名
            String name = fs.getName();

            //获取字段名数据类型
            Class type = fs.getType();
            String typeName = type.getSimpleName();

            //获取字段名修饰符
            int modifiers = fs.getModifiers();//返回值是修饰符的代号
            String str = Modifier.toString(modifiers);//将代号转化为字符串
}

修改属性的值:

  在不使用反射机制之前,我们如何修改属性的值?

public class Student {
    public int no;//整体是一个Filed对象
    private String name;
    protected int age;
    boolean sex;

    public Student() {
    }

    public Student(int no) {
        this.no = no;
    }
    public static void m(String s,int b){

    }
}

应该是这样的先创建对象:Student stu=new Student();

  然后修改属性的值:          stu.no=1;

必须有三个要素:对象,属性,值

反射机制要素需要这三个要素:

        //先获取整个类的Class
        Class studentClass = Class.forName("bean.Student");

        //获取Student对象
        Student obj = (Student)studentClass.newInstance();

        //获取no属性,通过属性名获取Field
        Field noFiled = studentClass.getDeclaredField("no");

        //给obj对象的no属性赋值
        noFiled.set(obj,111);//包含三要素:对象,no属性,值

        //获取属性的值,通过get()方法
        System.out.println(noFiled.get(obj));//两要素:对象,属性名

        //给私有属性赋值,反射机制访问私有属性
        Field nameField = studentClass.getDeclaredField("name");

        //需要是要setAccessible()方法打破封装才能修改值
        nameField.setAccessible(true);
        nameField.set(obj,"jack");

通过反射机制获取方法以及调用方法:

与方法相关的类java.lang.reflect.Method

与获取属性名类似,可以使用method.getDeclaredMethods()获取所有的方法。

        Class cls=Class.forName("bean.Student");
        Method[] methods = cls.getDeclaredMethods();
        
           for (Method method:methods){

           //获取修饰符列表,与获取属性修饰符一样
            System.out.println(Modifier.toString(method.getModifiers()));

            //获取方法的返回值类型,getReturnType()返回的是一个Class,获取Class的简类名
            System.out.println(method.getReturnType().getSimpleName());

            //获取方法名
            System.out.println(method.getName());

            //获取参数类型,参数类型可能多个。返回值是一个Class数组
            Class[] parameterTypes = method.getParameterTypes();
            for (Class parameterType:parameterTypes){
                System.out.println(parameterType.getSimpleName());
            }
        }

也可以通过方法名加参数类型定位特定的方法,不能只使用方法名特定方法,因为Java中存在方法重载机制。

调用方法需要四要素:对象、方法名、实参、返回值

注意:getDeclaredMethod()方法是获得指定的方法,第一个参数是方法名,后面的参数是参数类型,使用相应类型的Class,可以有多个,这是一个可变形参。

invoke()中填写对象名,实参。返回值是一个Object对象

        //获取方法
        Class cls = Class.forName("bean.Student");
       
        //创建对象
        Object obj = cls.newInstance();

        //得到指定的方法
        Method method = cls.getDeclaredMethod("m", String.class, int.class);
        //调用对象四要素 对象,方法名,参数,返回值
        Object retValue = method.invoke(obj, "123", 1);

使用构造方法创建对象

只需要指定构造方法的类型就可以找到指定的构造方法,不需要写构造方法名。

        Class cls = Class.forName("bean.Student");
        //获取构造方法,区分构造方法只看参数就可以了
        Constructor constructor =                     
        cls.getDeclaredConstructor(int.class,String.class,int.class,boolean.class);
        Object o = constructor.newInstance(1,"刘哥",22,true);

也可以这样,直接通过获取整个Class,然后cls.newInstance(),但是这个方法自Java9之后不建议使用

            Class cla=Class.forName("bean.Student");
            //newInstance()会调用无参构造方法,所以要有无参
            Object obj=cla.newInstance();

通过反射获取父类以及实现的接口

        //获取String的父类
        Class cls = Class.forName("java.lang.String");
        Class superclass = cls.getSuperclass();
        System.out.println(superclass.getSimpleName());
        //获取String类实现的所有接口
        Class[] interfaces = cls.getInterfaces();
        for (Class in:interfaces){
            System.out.println(in.getName());
        }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值