1. java反射基础
反射的概念主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射的应用
1. Spring框架:IOC(控制反转)
2. Hibernate框架:关联映射等
3. 白盒测试
相关API
java.lang包下
1. Class<T>
:表示一个正在运行的 Java 应用程序中的类和接口,是Reflection的起源
java.lang.reflect包下
1. Field 类:代表类的成员变量(也称类的属性)
2. Method类:代表类的方法
3. Constructor 类:代表类的构造方法
4. Array类:提供了动态创建数组,以及访问数组的元素的静态方法
Class<T>
类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass方法自动构造的,因此不能显式地声明一个Class对象
Class是Reflection起源。要想操纵类中的属性和方法,都必须从获取Class object 开始
2. 创建测试单元
最后,随便在某个类中写一个方法在方法上加上 @org.junit.Test即可
3. 动态实例化
为什么要用动态实例化
1. 如果用new的方式直接创建对象,那就意味着程序已经写死了,java程序一般都是运行在千里之外的服务器上,现在我要千里之外动态的创建一个人User,我不可能把这个人创建出来,再重新部署上去,这就需要动态的创建对象。
创建对象的类有两种方式
1. User.class:直接创建对象的类
2. Class.forName(className):通过类的名字创建对象的类
4. 动态方法调用
获得当前类以及超类的public Method:
Method[] arrMethods = classType. getMethods();
获得当前类申明的所有Method:
Method[] arrMethods = classType. getDeclaredMethods();
获得当前类以及超类指定的public Method:
Method method = classType. getMethod(String name, Class<?>… parameterTypes);
获得当前类申明的指定的Method:
Method method = classType. getDeclaredMethod(String name, Class<?>… parameterTypes)
通过反射动态运行指定Method:
Object obj = method. invoke(Object obj, Object… args)
为了方便测试,添加单元测试Junit
动态获取类和执行类中方法的思路
获取类->Class.forName
1. 获取类对象后,这个Class类对象有很多方法,比如获取全部的类方法getDeclaredMethods()
2. 我们可以通过这个类创建实例对象,newInstance()
通过获取到的类,获取类中的方法->getMethod(methodName, new Class[] {pc})
1. 参数1:方法名字
2. 参数2:这是一个类数组,里面存放方法的参数类型,我们可以通过Class.forName(paramType),来获取到一个参数的类型,比如paramType=“java.lang.String”
执行获取到的方法->invoke()
1. 第一个参数传实例对象,第二个传参数
5. 动态属性访问
代码可以看当前目录下的image里的图片
通过反射调用Field变量
获得当前类以及超类的public Field:
Field[] arrFields = classType. getFields();
获得当前类申明的所有Field:
Field[] arrFields = classType. getDeclaredFields();
获得当前类以及超类指定的public Field:
Field field = classType. getField(String name);
获得当前类申明的指定的Field:
Field field = classType. getDeclaredField(String name);
通过反射动态设定Field的值:
fieldType.set(Object obj, Object value);
通过反射动态获取Field的值:
Object obj = fieldType. get(Object obj) ;
Field是属性
只要用到反射,先获得Class Object
没有方法能获得当前类的超类的private方法和属性,你必须通过getSuperclass()找到超类以后再去尝试获得通常情况即使是当前类,private属性或方法也是不能访问的,你需要设置压制权限setAccessible(true)来取得private的访问权。但这样就破坏了面向对象的规则,所以除非万不得已,尽量少用。
更多反射相关内容,百度一下,你就知道
6. 获取类名
Class clazz = Class.forName(path);
clazz.getName();// 获取完整类名com.sg.myReflection.bean.User
clazz.getSimpleName();// 直接获取类名 User
7. 反射自动生成SQL语句
编写给任意对象,自动生成SQL语句insert into,对象的类,使用一个对象,生成一个SQL语句,假设表名和类名相同。返回的SQL语句格式为:
INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,…)
获取SQL语句方法的大概思路:
1. 定义一个可变的字符串StringBuffer
2. 使用append()方法对字符串进行追加
3. 使用反射获取对象类名,类中的属性名称