java之反射和BeanUtils类

    反射和BeanUtils类

1. 类的初始化:类什么什么情况下会加载到内存中

只要类加载到内存中,那么类加载器就会为这个类创建一个class文件对象

2. javaBean:数据库中的表和java中的类对应关系

javaBean中包含的内容:

1> 私有的成员变量

2> 公共的get/set方法

3> 空参数构造方法(默认)

4> toString方法

5> 实现序列化接口

3. 获取Class文件的三种方式:

1> 使用Object类中的方法

Class<?> getClass() 返回此 Object 的运行时类。

2> 可以使用类的class属性

任意一种数据类型(基本类型4类8种,引用类型(类,接口,数组))

java都会为这种数据类型赋予一个class属性

3> 可以使用Class类的静态方法获取

static Class<?> forName(String className) 返回与带有给定字符串名的类或接口相关联的 Class 对象。

方法的参数:

String className:全类名(包名+类名)

4. 使用反射技术获取类中的构造方法,并实例化这个构造方法(创建对象)

实现步骤:

1> 获取Person类的class文件对象

2> 使用class文件对象中的方法getConstructor获取构造方法Constructor

3> 使用Constructor类中的newInstrance方法实例化Person对象

使用前提:

1> 类中必须有空参数构造方法

2> 空参数构造方法的修饰符不能是private,建议使用public

构造方法

public Person()

public Person(String name, int age, String sex)

private Person(String name, int age)

1> Constructor<?>[] getConstructors() 获取的是所有公共构造方法

Constructor<?>[] getDeclaredConstructors() 获取类声明(定义)的所有构造方法

Constructor<T> getConstructor(Class<?>... parameterTypes) 获取指定公共构造方法。

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取指定构造方法。包含私有的

参数:

... 可变参数,可以写,可以不写,可以写多个(0,1,多个)

Class<?>... parameterTypes:构造方法参数的Class文件对象

2> T newInstance(Object... initargs)

使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

参数:

Object... initargs:调用构造方法,实际传递的参数

返回值:

T:返回的是Object对象,这个Object对象就是Person对象(多态)

3> Method[] getMethods() 获取的类和父类中所有的公共成员方法

Method[] getDeclaredMethods() 公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

4> Method getMethod(String name, Class<?>... parameterTypes) 获取指定公共成员方法。

Method getDeclaredMethod(String name, Class<?>... parameterTypes) 获取指定已声明方法。包含私有的

方法的参数:

String name:方法的名称

Class<?>... parameterTypes:方法参数的class文件对象,String.class,int.class

5> 使用Method类中的方法invoke执行获取到的方法

java.lang.reflect.Method

Object invoke(Object obj, Object... args)

对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

参数:

Object obj:对象,方法的执行必须有对象支持,要你执行的方法属于哪个对象,就传递哪个对象

传递Person,可以使用反射快速创建对象方式获取

Object... args:调用方法传递的实际使用的参数(值)

返回值:

Object:如果方法有返回值,则返回对应的值,值由各种数据类型,所以使用Object类型接收

如果方法的返回值类型是void,没有返回值,则Object的值是null

6> private void method()

私有方法不能直接使用,需要取消java的访问权限检查

java.lang.reflect.Method extends java.lang.reflect.AccessibleObject

privateMethod.setAccessible(true);//暴力反射

私有构造方法不能创建对象使用,有权限检查,会抛出IllegalAccessException:非法的权限访问异常

可以使用Constructor的父类AccessibleObject中方法设置方法的访问权限

java.lang.reflect.AccessibleObject

void setAccessible(boolean flag) 将此对象的 accessible 标志设置为指示的布尔值。

值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。

值为 false 则指示反射的对象应该实施 Java 语言访问检查。

暴力反射不推荐,破坏了类的封装性

* 反射综合案例:

通过反射技术,获取JavaBean的对象,给JavaBean的成员变量注入(赋)值

* 实现步骤:

1> 创建一个properties配置文件存储成员变量的名字和值

2> 使用Properties集合+IO流,读取配置文件,把健和值保存到Properties集合中

3> 使用反射技术获取javabean的class文件对象

4> 使用反射技术快速创建javabean对象

5> 遍历存储键值对的Properties集合,获取每一对键值

6> 使用获取到的健,拼接setXXX方法

7> 使用反射技术根据拼接的setXXX方法,获取方法的Method对象

8> 使用反射技术调用Method对象中的方法invoke给成员赋值(value)

5. 使用Apache提供的工具类BeanUtils,给成员变量赋值,获取成员变量的值

注意:

BeanUtils可以操作的数据类型有:基本数据类型(4类8种),基本类型的包装类,String类型;以上三种类型的数组形式

BeanUtils赋值的时候,可以把字符串类型的基本类型的值,转换为基本类型给成员变量赋值 相当于 Integer.parseInt("100");

综合案例:

读取XML中的配置文件信息,使用反射技术创建JavaBean对象,使用BeanUtils将XML中的数据保存到JavaBean类的属性中

实现步骤:

1> 定义两个javabean类,Person,Student

2> 定义一个xml文件,存储javabean的全类名和属性名属性值(属性--变量)

3> 使用dom4j解析xml文档,获取javabean的全类名和属性名属性值

4> 使用反射技术,通过获取的全类名,创建javabean对象

5> 使用BeanUtils工具类中的的方法setProperty给成员变赋值