day016 反射

本文详细介绍了Java的反射机制,包括类的加载时机、加载过程、反射概述,特别是类的Class对象获取方式、反射获取构造方法、成员方法和成员变量的详细步骤。通过实例演示了反射在创建对象、调用方法、访问属性等方面的使用,并探讨了反射带来的好处。此外,还讲解了内省(Introspector)的使用以及Apache BeanUtils工具类在简化JavaBean操作上的作用。
摘要由CSDN通过智能技术生成

1 反射

1.1 类的加载时机

1. 创建类的实例

2. 类的静态变量,或者为静态变量赋值

3. 类的静态方法

4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

5. 初始化某个类的子类

6. 直接使用java.exe命令来运行某个主类

 

不用背,就是用到了这个类,这个类就会被加载进内存。

1.2 类的加载过程

三步

类的加载过程.png

1.3 反射概述

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

栈:用来运行方法,每一个方法运行偶读在栈里开辟空间。

堆:用来存放对象。

方法区:保存字节码文件信息(保存类的信息)。

反射介绍.png

引导类加载器也叫根类加载器。

反射主要操作的是类的Class类型对象。

双亲委派模型

双亲委派模型.png

1.4 反射前的准备工作

(插播:

javabean  

就是一个类,这个类要满足三个要求。

1. 把属性私有。

2. 提供set/get方法和空参构造。

3. 要实现Serializable 接口。 (可以省略)

这样的类一般放在一个包里,这个包通常叫做bean或pojo或者domain或model。

Person类

public class Person {
    private String name;
    private int age;
    public String address;
    public String city;
    
    private void hitBeanBean() {
        System.out.println("打豆豆");
    }
    
    public void sleep(String address, int time) {
        System.out.println("在" + address + "睡了" + time + "秒");
    }
    
    public void eat() {
        System.out.println("吃饭饭");
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
    }
    private Person(int age) {
        this.age = age;
    }
    Person(String name) {
        
    }
}

1.5 Class对象的三种获取方式

一个类的Class类型对象的三种获取方式

 

1. 通过对象.getClass()方法获取到。

对象名.getClass();  

这个getClass方法是Object对象中的,所以任何对象都有这个方法。

 

2. 类名获取(最简便)

类名.class

 

3. 通过Class这个类的静态方法进行获取。(最常用,可以把信息放到配置文件中,最灵活)

forName(String className): 根据类名获取到这个类的Class类型的对象。 参数类名必须是全类名(包含包的类名)

 

任何数据类型都有class属性。包括基本类型

一个类只会创建一个Class类型的对象。

import cn.itcast.bean.Person;

public class Demo01Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        //通过对象.getClass()方法获取到。
        Person p = new Person();
        //调用getClass拿到这个类的Class类型的对象
        Class clazz1 = p.getClass();//这个类型是Class,不是Person。只不过这个类中的内容是用来描述Person类的。
        System.out.println(clazz1);
        
        //类名获取
        Class clazz2 = Person.class;
        System.out.println(clazz2);
        
        //通过Class这个类的静态方法进行获取。
        Class clazz3 = Class.forName("cn.itcast.bean.Person");
        System.out.println(clazz3);
        
        
        System.out.println(clazz1 == clazz2);//true
        
    }
}

1.6 反射获取构造方法

1.6.1 反射获取空参构造方法并创建对象

反射获取构造方法。

Constructor[] getConstructors(): 获取这个类中的所有的【公共】的构造方法。

Constructor getConstructor(Class... parameterTypes):获取到指定的【公共】的构造方法。 parameterTypes 表示要获取的构造方法的参数列表

 

                Constructor表示构造方法,里面有一个方法,可以完成一些功能。

                            T newInstance(Object... initargs):通过此构造方法创建一个对象。  

参数 initargs:表示调用构造方法时传递的实际参数。

返回值:表示创建的对象。

import java.lang.reflect.Constructor;

import cn.itcast.bean.Person;

public class Demo01Reflect {
    public static void main(String[] args) throws Exception {
        method2();
    }
    
    /*
     * Constructor getConstructor(Class... parameterTypes):获取到指定的【公共】的构造方法。 parameterTypes 表示要获取的构造方法的参数列表
     * 获取到空参数的构造方法,并且使用空参数的构造方法创建对象。
     */
    public static void method2() throws Exception {
        //获取这个Person的Class类型的对象
        Class clazz = Class.forName("cn.itcast.bean.Person");
        //获取指定的构造方法(空参数构造)。
        Constructor con = clazz.getConstructor(); //如果获取空参数构造,调用getConstructor方法,参数什么都不需要写。
        //此时con表示的就是空参数构造方法
        //使用空参构造创建一个对象
        Object obj = con.newInstance();//newInstance方法参数表示调用构造方法时传递的实际参数,因为此时调用的是空参数构造,所以不需要传递。
        //强转成Person
        Person p = (Person)obj;
        
        System.out.println(p.getName() + "--" + p.getAge());
        
    }
    
    
    /*
     * Constructor[] getConstructors(): 获取这个类中的所有的公共的构造方法。
     */
    public static void method1() throws Exception {
        //获取这个Person类的Class类型的对象
        Class clazz = Class.forName("cn.itcast.bean.Person");
        //Constructor[] getConstructors(): 获取这个类中的所有的公共的构造方法(public修饰的  )。
        Constructor[] cons = clazz.getConstructors();
        //遍历数组,打印里面的内容
        for(Constructor c : cons) {
            System.out.println(c);
        }
    }
}

1.6.2 反射获取有参构造方法并创建对象


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值