反射原理和运用场景

1.什么是反射

反射,通俗的说,即在程序运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能知道这个对象的所有属性和方法。这种动态获取信息及动态调用对象的方法的功能叫做Java的反射机制。

2.反射和类加载过程的区别

以无参构造为例

正常类加载和创建对象过程:

Java源代码-->类编译器编译成.class文件-->类加载器(ClassLoader)将字节码文件加载到JVM的各个区域;

对象创建: 

Person per = new Person();

--编译期加载class文件--》查找构造函数Person()-->通过构造函数Person()创建对象。

反射的加载和对象创建过程:

直接解析class文件,得到类的属性和方法;

对象创建:

Class personClass = Class.forName("com.xiaohan.reflect.Person");//通过全路径名获取Class对象
Constructor con = personClass.getConstructor();//获取无参/有参构造函数
Person person = (Person)con.newInstance();//通过构造函数创建对象

3.创建class对象的三种方式

3.1在没有类实例的情况下(类.class)

Class personClass = Person.class;

3.2有实例的情况下(实例.getClass())

Person p = new Person();
Class pclass = p.getClass();

3.3通过类的全路径名(Class.forName("类的全路径名"))

Class personClass = Class.forName("com.xiaohan.reflect.Person");

以上三种方式获得的Class对象是相等的,

4.通过反射方式获取类的属性和方法

4.1创建一个类(Person)

package com.xiaohan.reflect;
/**
 * 定义各种类型和访问权限的属性和方法,验证后面是否都可以通过反射的方式获取到所有属性和方法
 */
public class Person {
    public String name = "xiaohan";
    protected Integer age = 1;
    private Byte sex = (byte)1;
    Boolean isMarriage = true;

    public Person() {
    }

    public Person(String name, Integer age, Byte sex, Boolean isMarriage) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.isMarriage = isMarriage;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Byte getSex() {
        return sex;
    }

    public void setSex(Byte sex) {
        this.sex = sex;
    }

    public Boolean getMarriage() {
        return isMarriage;
    }

    public void setMarriage(Boolean marriage) {
        isMarriage = marriage;
    }
}

 4.2通过反射的方式获取类中的各个属性和方法

4.2.1通过无参或有参构造创建对象

 public static void main(String[] args) throws Exception {
        //获取Class对象
        Class personClass = Class.forName("com.xiaohan.reflect.Person");
        //方式1:通过无参构造函数创建对象
        Constructor constructor = personClass.getConstructor();
        Person person = (Person)constructor.newInstance();
        //方式2:通过有参构造创建对象
        Constructor constructor1 = personClass.getConstructor(String.class,Integer.class, Byte.class, Boolean.class);
        Person person1 = (Person) constructor1.newInstance("xiaohan",2,(byte)3,false);
        
    }

4.2.2获取属性

公有属性获取

 /**
         * 获取对象的属性
         * getField:只能获取public的,包括从父类继承来的字段
         * getDeclaredField:可以获取本类中所有的字段,包括private的;注,这里只能获取到private的字段,并不能访问该private字段的值,
         * 除非加上setAccessible(true).
         */
        //public修饰的属性
        //Field nameFiled = personClass.getField("name");
        Field field = personClass.getDeclaredField("name");
        String name = String.valueOf(field.get(person));//通过传入实例,获取具体哪一个实例字段的值
        String name2 = String.valueOf(field.get(person1));//通过传入实例,获取具体哪一个实例字段的值
        System.out.println("person实例:"+name);
        System.out.println("person1实例"+name2);

私有属性获取

//获取私有属性
        Field filed2 = personClass.getDeclaredField("sex");
        filed2.setAccessible(true);
        //获取具体实例的属性
        Byte sex = (Byte) filed2.get(person);
        Byte sex2= (Byte) filed2.get(person1);
        System.out.println("私有属性获取person:"+sex);
        System.out.println("私有属性获取person1:"+sex2);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值