温馨提示 : 如果还没有看JAVA反射基础的童鞋,请移步至上一篇 JAVA反射(一)
JAVA中用反射修改属性
在上一节中写了如何获取类的信息和属性.今天谈一谈如何动态修改属性的值
1.获取字节码对象,以User作为例子
User user = new User();
Class clazz = user.getClass();
2.获取属性元数据,以获取某个特定的;
Field field = clazz.getFild("userid");
3.用filed提供的方法来动态修改和显示属性值
field.set(user,"123");//第一个参数:field元数据的对象,第二个参数:要设置的值
filed.get(user);//传递对象就可以获取到属性的值
JAVA中用反射获取构造方法
获取构造方法有什么用呢?
个人认为最有用的就是获取类实例(对象)
1.获取字节码对象
Class clazz = User.class;
2.获取Constructor类
Constructor clazz.getConstructor(parameterTypes)//根据参数类型获取构造方法(可以没有参数,默认调用无参构造方法);
Constructor[] clazz.getConstructors()//获取所有构造方法
3.返回该字节码对象对应类的实例
Object obj = constructor.newInstance();//推荐使用
Object obj = clazz.newInstance()//JDK9之后已经不再推荐使用(过期的)
JAVA中用反射做简单的数据查询映射,以及如何将vo与数据库之间映射
package com.tangbaobao.reflect;
/**
* @author 唐学俊
* @version 创建时间:2017年11月4日 下午1:41:41
*
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.tangbaobao.domain.User;
import com.tangbaobao.utils.DBSUtils;
public class Test4 {
public static void main(String[] args) {
User user = new User();
List<Object> queryAll = queryAll(user);
System.out.println(queryAll.size());
for (Object object : queryAll) {
System.out.println(object);
}
}
// 返回查询结果集
public static <T> List<T> queryAll(Object obj) {
// 定义承载记录集的集合
List<T> list = new ArrayList<T>();
// 获取字节码对象
Class<T> clazz = (Class<T>) obj.getClass();
// 获取domain的属性
Field[] fields = clazz.getDeclaredFields();
// 书写sql语句
String sql = "select *from " + clazz.getSimpleName();
// JDBC方面
Connection conn = DBSUtils.getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
// 将rs查询记录集与domain表映射
while (rs.next()) {
//新建对象
Constructor<T> instance = clazz.getConstructor();
T user = instance.newInstance();
//clazz.newInstance();jdk9之后过时了
for (Field field : fields) {
field.setAccessible(true);
field.set(user, rs.getObject(field.getName()));
}
list.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
}
JAVA中用反射获取普通方法
我们知道,Java中一个类里面包括,属性,,普通方法,构造方法,利用反射机制,我们可以获取到类中上述所有.
1.首先获得Class 实例,也就是字节码对象,以User类来举例.
Class clazz = User.class
2.获得Method类
Method clazz.getMethod(Object obj,Object...args)//获取指定共有方法的元数据
Method[] clazz.getMethods();//获取共有类的方法元数据(包括父类)
Method clazz.getDeclaredMethod(Object obj,Object...args)//可以获得当前类指定方法的元数据(任意方法)
Method[] class.getDeclaredMethods();//获取当前类所有方法
3.Method类提供的方法
一个方法由四部分组成:修饰符,返回值类型,方法名,参数列表下面,从这四个方面来学习Method提供的API
Method[] method = clazz.getMethods();
for(Method me:method){
System.out.println("访问修饰符:"+me.getModifiers());
System.out.println("返回值类型:"+me.getReturnType());
System.out.println("方法名:"+me.getName());
me.getParameterType();
}
4.用invoke(Object obj,Object…)执行方法
//获取指定方法
Method declaredMethod = clazz.getDeclaredMethod("setUserid",String.class);
//获得类的实例
Constructor<?> constructor = clazz.getConstructor();
Object user = constructor.newInstance();
执行方法
declaredMethod.invoke(user, "sfsf");
//获取get方法
Method method = clazz.getMethod("getUserid");
System.out.println("执行"+method.invoke(user));
总结
通过反射的学习,学了很多API,知识点,但是总结来说,用以下模式,或者掌握以下几点,就OK了
- 什么是反射?
- 为什么学习反射?
- 怎么学?
前两点不说,来讨论第三点
- 学字节码对象,就是看.class中有那些东西?
- 获取这些东西的信息,每个有不同的类来获取元数据(Field,Method,Constructor)
- 获取这些元数据来做什么(getName(),set(),get(),getReturnType()……)
其实学懂类中的一个,按照这个套路,就都会了.当然,我估计这只是反射的皮毛,更深的东西等着我们去发掘…..