类的反射

Posted guofx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的反射相关的知识,希望对你有一定的参考价值。

一丶基本概述

类的反射是非常重要的一个知识点,许多框架都是依赖这个技术。所谓的反射就是在运行状态中通过类就可以获取类中的所有构造方法,变量以及方法(包括静态,以及私有都可以)。

实际上,我们创建的每一个类也都是对象,都是java.lang.Class的对象。既然是类的反射那么类Class就是其中的重点了,下面来介绍一下Class。

技术图片

在网上看到一张关于类加载的图片,非常形象大家可以参考一下

技术图片

二丶反射的具体使用

假设现在有一个实体类Student

package reflect;

public class Student 

    public static int age ;

    private String name;

    protected int no;

    String hobby;

    public Student(int no)
        this.no = no;
    

    protected Student(int no,String name)
        this.name = name;
        this.no = no;
    

    private Student(String name)
        this.name = name;
        this.no = no;
    

    public int getAge() 
        return age;
    

    public void setAge(int age) 
        this.age = age;
    

    public int getNo() 
        return no;
    

    public void setNo(int no) 
        this.no = no;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getHobby() 
        return hobby;
    

    public void setHobby(String hobby) 
        this.hobby = hobby;
    

    public void sayHi(String name)
        System.out.println(name + "sayHi");
    

    private void sayGoodbye(String name)
        System.out.println(name + "sayGoodbye");
    

    @Override
    public String toString() 
        return "Student" +
                "age=" + age +
                ", name=‘" + name + ‘\\‘‘ +
                ", no=" + no +
                ", hobby=‘" + hobby + ‘\\‘‘ +
                ‘‘;
    

获取类对象的方法有三种

        Class cls1 = Student.class;
        Class cls2 = Class.forName("reflect.Student");
        Student stu = new Student();
        Class cls3 = stu.getClass();
        //可以验证Class对象只创建一次
        System.out.println(cls1 == cls2);
        System.out.println(cls1 == cls3);

获取构造方法

    public static void getConstrucor() throws Exception
        Class cls = Student.class;
        //获取所有公有的构造
        Constructor[] cons = cls.getConstructors();
        for(Constructor con : cons)
            System.out.println(con);
        
        //获取所有构造
        Constructor[] deCons = cls.getDeclaredConstructors();
        for(Constructor con : deCons)
            System.out.println(con);
        
        //获取指定参数类型的公有构造
        Constructor con1 = cls.getConstructor(int.class);
        //通过构造方法创造一个Student对象
        Student obj1 = (Student)con1.newInstance(3);
        System.out.println(obj1.toString());
        //获取指定类型参数的构造(无视修饰符)
        Constructor con2 = cls.getDeclaredConstructor(String.class);
        //破解私有的权限,不加报错
        con2.setAccessible(true);
        //通过构造方法创造一个Student对象
        Student obj2 = (Student)con2.newInstance("张三");
        System.out.println(obj2.toString());
    

  获取成员变量

    public static void getField() throws Exception 
        Class cls = Student.class;
        //获取所有成员变量包括
        Field[] fields1 = cls.getDeclaredFields();
        for(Field f : fields1)
            System.out.println(f);
        
        System.out.println("--------------");
        //只能获取公有的成员变量
        Field[] fields2 = cls.getFields();
        for(Field f : fields2)
            System.out.println(f);
        
        System.out.println("--------------");
        Student stu = new Student();
        //给成员变量赋值,其实和构造方法没什么差别。
        // 参数是成员变量名
        Field f1 = cls.getDeclaredField("name");
        //私有需要破解权限
        f1.setAccessible(true);
        //需要传入一个对象来设置
        f1.set(stu,"张三");
        System.out.println(stu.toString());

        Student stu2 = new Student();
        Field f2 = cls.getField("age");
        f2.set(stu2,21);
        System.out.println(stu2.toString());
    

  成员方法的调用

    public static void getMethod() throws Exception
        Class cls = Student.class;
        //获取所有方法,包括构造方法
        Method[] methods = cls.getDeclaredMethods();
        for(Method m : methods)
            System.out.println(m);
        
        System.out.println("----------------------");
        //和之前大同小异,但是这个会获取到父类的所有公有方法
        Method[] methods2 = cls.getMethods();
        for(Method m : methods2)
            System.out.println(m);
        
        //获取方法时候和之前不同的就是需要传入两个参数一个是方法名,一个是参数类型
        Method m = cls.getMethod("sayHi", String.class);
        //调用方法需要传入对象以及方法参数
        //通过无参构造方法新建一个对象
        m.invoke(cls.getConstructor(null).newInstance(),"张三");
    

  以上就是简单的一些反射知识,有了反射我们可以通过配置文件传入类名,然后用Class.forName()来获取类对象,对于一些特地的场景非常的实用

 

以上是关于类的反射的主要内容,如果未能解决你的问题,请参考以下文章

《类的加载与反射》第3节:反射

Java反射机制详解

反射(高大上)类的内置方法

java反射学习之一反射机制概述

java反射基础知识反射应用实践

说说对java反射的理解,使用反射如何获取一个类的所有方法,使用反射需要注意哪些问题?