深度理解JAVA 反射机制

JAVA 反射机制是非常基础也是非常重要的板块,经过自己的总结,希望能帮到更多的朋友一起理解,大牛请绕道

首先反射有以下三种实现方式
1: Class.forName(“全类名”),将字节码文件加载进内存,返回Class对象
* 多用于配置文件,将类名定义在配置文件中,读取文件,加载类
2: 类名.Class : 通过类名的属性class获取
* 多用于参数的传递
3: 对象.getClass(), getClass()方法在Object类中定义着。
* 多用于对象的获取字节码的方式

由此我们可以得出以下结论:
同一个字节码文件(*.Class)在一次程序运行过程中,只会被加载一次,不论通过那一种方式获取的class对象都是同一个

Class 对象功能
获取功能:
1:获取成员变量们
Filed[] getFields() //获取所有的public 修饰的成员变量
Filed getFiled(String name) // 获取指定名称的public 修饰的成员变量
Filed[] getDeclaredFields()
Filed[] getDeclaredField(String name)

  2:    获取构造方法们
         Constructor[] getConstructors()
         Constructor getConstructor(类… parameterTypes)
         
          Constructor[] getDeclaredConstructors()
          setAccessible(true)   // 忽略访问权限修饰的安全检查,称为暴力反射
         Constructor getDeclaredConstructor(类… parameterTypes)

  3:获取成员方法们
          Method[]  getMethods()
          Method   getMethod(String name,类... parametertypes)

          Method[]  getDeclaredMethods()
          Method   getDeclaredMethod(String name,类... parametertypes)
  4: 获取类名
          String   getName();

Field: 成员变量

  1. 设置值 void set(Object obj,Object value)
  2. 获取值 get(Object obj)
  3. 忽略访问权限修饰符的安全检查

下面用代码的方式展现下基本的使用功能,首先创建一个Persion类

package com.charles.excel.Controller;

public class Persion {
    private String name;
    int age;
    public String address;

    public Persion() {
    }

    private Persion(String name) {
        this.name = name;
    }

    Persion(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Persion(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public void show() {
        System.out.println("show方法的输出");
    }

    public void method(String s) {
        System.out.println("method方法的输出: " + s);
    }

    public String getString(String s, int i) {
        return s + "---" + i;
    }

    private void function() {
        System.out.println("function方法的输出");
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address="
                + address
                + "]";
    }
}

创建Main方法执行观察效果

package com.charles.excel.Controller;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class TestPersion  {
    public static void main(String[] args) throws Exception {
        // 获取字节码文件对象
        Class c = Class.forName("com.charles.excel.Controller.Persion");
        // 只能获取公共的成员变量
        Field[] fields1 = c.getFields();
        for (Field field : fields1) {
            System.out.println(field);
        }
        System.out.println("-----------------------------------------");
        // 获取所有的成员变量
        Field[] fields2 = c.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println(field);
        }

        // 通过无参构造方法创建对象
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        // 获取单个的成员变量
        // 获取address并对其赋值
        Field addressField = c.getField("address");
        // 给obj对象的addressField 字段设置值为"上海"
        addressField.set(obj, "上海");
        System.out.println(obj);

        // 获取name并对其赋值
        Field nameField = c.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(obj, "Charles");
        System.out.println(obj);

        // 获取age并对其赋值
        Field ageField = c.getDeclaredField("age");
        ageField.setAccessible(true);
        ageField.set(obj, 24);
        System.out.println(obj);
    }
}

小伙伴们通过今天的分享,相信你是否懂了反射的原理了呢?

你可能感兴趣的:(面试干货,反射,java)