Java反射机制详细总结!

文章目录

  • 1、反射
  • 2、Class对象
  • 3、反射的应用
    • 3.1、类信息相关操作
    • 3.2、类的构造方法
    • 3.3、类的普通方法
    • 3.4、类的属性

1、反射

  Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类和类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。

反射的好处:

  1. 反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力;
  2. 通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类;
  3. 使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法;
  4. 反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中

  正是反射有以上的特征,所以它能动态编译和创建对象,极大的激发了编程语言的灵活性,强化了多态的特性,进一步提升了面向对象编程的抽象能力。

2、Class对象

  想要进行反射,就必须获得类的Class对象!

  想要创建一个对象,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三个步骤对该类进行初始化。在这个过程中,该类产生了三种阶段的类型:源码阶段(.class文件),Class对象阶段,运行时对象阶段。因为这三种阶段的存在,也就产生了三种会的Class对象的方式。

Java反射机制详细总结!_第1张图片

/**
 * @author RuiMing Lin
 * @date 2020-03-10 21:50
 */
public class Demo1 {
     
    public static void main(String[] args) throws Exception{
     
        //获取Class对象:源码阶段(.class文件),Class对象阶段,运行时对象阶段

        Class cla1 = Class.forName("Person");//.class文件阶段
        Class cla2 = Person.class;//Class对象阶段

        Person person = new Person();
        Class cla3 = person.getClass();//运行时对象阶段

        System.out.println(cla1 == cla2);//True
        System.out.println(cla1 == cla3);//True
    }
}

   自定义一个Person类,通过三种方式获得一个Class对象,经过比较,得出三者都是指向同一个Class对象。

3、反射的应用

3.1、类信息相关操作

import domain.Person;
/**
 * @author RuiMing Lin
 * @date 2020-03-10 22:28
 */
public class Demo3 {
     
    public static void main(String[] args) throws Exception{
     
        Class cla = Class.forName("domain.Person"); //获得Class对象

        System.out.println(cla.getPackage());   //获取包名
        System.out.println(cla.getSuperclass());//获取父类
        System.out.println(cla.getInterfaces());//获取接口
        System.out.println(cla.getName());//获取类名
    }
}

3.2、类的构造方法

import domain.Person;

import java.lang.reflect.Constructor;

/**
 * @author RuiMing Lin
 * @date 2020-03-10 22:28
 */
public class Demo3 {
     
    public static void main(String[] args) throws Exception{
     
        Class cla = Class.forName("domain.Person"); //获得Class对象

        //获取public修饰的构造方法
        Constructor constructor1 = cla.getConstructor();    //获取无参构造
        Constructor constructor2 = cla.getConstructor(String.class, int.class); //获取有参构造
        Constructor[] constructors = cla.getConstructors(); //获取所有构造方法

        //遍历
        for (Constructor constructor : constructors) {
     
            System.out.println("constructor = " + constructor);
        }

        //获取所有修饰符修饰的构造方法
        Constructor declaredConstructor1 = cla.getDeclaredConstructor();
        Constructor declaredConstructor2 = cla.getDeclaredConstructor(String.class, int.class);
        Constructor[] declaredConstructors = cla.getDeclaredConstructors();

        //通过构造方法创建对象
        Person person = (Person) constructor2.newInstance("张三", 23);
        System.out.println("person = " + person);
        
        // Instance
        Person person = (Person)constructor2.newInstance("小明", 23);
        System.out.println("person = " + person);
    }
}

3.3、类的普通方法

import domain.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * @author RuiMing Lin
 * @date 2020-03-10 22:28
 */
public class Demo3 {
     
    public static void main(String[] args) throws Exception{
     
        Class cla = Class.forName("domain.Person"); //获得Class对象

        
        //获取public修饰的方法
        Method method1 = cla.getMethod("setName",String.class);
        Method[] methods = cla.getMethods();
        
        //获取所有修饰符修饰的方法
        Method declaredMethod = cla.getDeclaredMethod("setName", String.class);
        Method[] declaredMethods = cla.getDeclaredMethods();
        
        // 方法执行
        Constructor constructor = cla.getConstructor(); // 无参构造
        Person person = (Person)constructor.newInstance();
        System.out.println("执行方法前person = " + person);
        method1.invoke(person, "小明");
        System.out.println("执行方法后person = " + person);
    }
}

3.4、类的属性

  具体操作与上述均类似,在此就不演示了。

  1. Field[ ] getFields() :获取所有public修饰的成员变量
  2. Field getField(String name) :获取指定名称的 public修饰的成员变量
  3. Field[] getDeclaredFields(): 获取所有的成员变量,不考虑修饰符
  4. Field getDeclaredField(String name)
  5. void set(Object obj, Object value):设置值
  6. get(Object obj):获取值
  7. setAccessible(true) :是否暴力反射
import java.lang.reflect.Field;

/**
 * @author RuiMing Lin
 * @date 2020-12-21 20:45
 * @description
 */
public class Properties {
     
    public static void main(String[] args) throws Exception{
     
        Class<?> cla = Class.forName("Person");

//        cla.getField("")
        Field[] fields = cla.getFields();
        for (Field field : fields) {
     
            System.out.println("field = " + field);
        }

//        cla.getDeclaredField("")
        Field[] declaredFields = cla.getDeclaredFields();
        for (Field declaredField : declaredFields) {
     
            System.out.println("declaredField = " + declaredField);
        }

        Person person = new Person("小明", 23);
        declaredFields[0].setAccessible(true);
        Object o = declaredFields[0].get(person);
        System.out.println("o = " + o);
    }
}

你可能感兴趣的:(Java,java,反射)