阿哲学了就来聊——Java反射
概念
reflect 反射 ,反转 权力的转让
类中有很多的方法和属性,方法的调用权限,属性的赋值权限,属于对象的。
让对象把这些权力交出来,交给Class和其它反射类(Field,Method,Contructor)管理。
Class类 的范围就是天下所有的字节码文件,每一个类被编译成字节码文件后,都可以看成是Class类的对象
- 与Java反射相关的类如下:
类名 | 用途 |
---|---|
Class类 | 代表类的实体,在运行的Java程序中表示类和接口 |
Field类 | 代表成员变量(成员变量也成为属性) |
Mehod | 代表类的方法 |
Construtor类 | 代表类的构造方法 |
Class类
Class类代表实体,在运行Java应用程序中表示类和接口。这个类中提供了很多有用的方法,这里对他们的分类进行简单介绍。
获得类的相关方法
方法 | 用途 |
---|---|
asSubclass(Class class) | 把传递的类和对象转换成代表其子类的对象 |
Cast | 把对象转换成代表类或是接口对象 |
getClassLoader() | 获得类的加载器 |
getClasses() | 返回一个数组,该数组中含该类中有所有的公共类和接口类的对象 |
getDeclaredClasses | 返回一个数组,该数组中包含该类所有的类和接口对象 |
forName(String className) | 根据类返回类的对象 |
getName() | 获得类的完整路径名字 |
newInstance() | 创建类的实例 |
getPackage() | 获得类的包 |
getSimpleName() | 获得类的名字 |
getSuperclass() | 获得当前类继承的父类的名字 |
getInterfaces() | 获得当前实现的类或者是接口 |
获得类中属性相关的方法
方法 | 用途 |
---|---|
getFiled(String name) | 获得某个共有的属性对象 |
getDFileds() | 获得所有的共有属性对象 |
getDeclaredFiled ( String name ) | 获得某个属性对象 |
getDeclaredFileds ( String name ) | 获得所有属性对象 |
获得类中构造器的相关方法
方法 | 用途 |
---|---|
getMethod(String name, Class…<?> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class…<?> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
Field
Field代表类的成员变量(成员变量也称为类的属性)。
方法 | 用途 |
---|---|
equals(Object obj) | 属性与obj相等则返回true |
get(Object obj) | 获得obj中对应的属性值 |
set(Object obj, Object value) | 设置obj中对应属性值 |
Method类
Method代表类的方法。
方法 | 用途 |
---|---|
invoke(Object obj, Object… args) | 传递object对象及参数调用该对象对应的方法 |
Constructor类
Constructor代表类的构造方法。
方法 | 用途 |
---|---|
newInstance(Object… initargs) | 根据传递的参数创建类的对象 |
作用
- 获取Class对象
@Test
public void test1(){
// 1.获取某个类的实体类对象:三种方式
Class<Emps> c1 = Emps.class;
Class<?extends Emps> c2 = new Emps().getClass();
try {
Class<?> c3 = Class.forName("com.web.pojo.Emps");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//2.分别对实体类的成员(属性,方法,构造方法)进行托管
}
构造方法
@Test//使用构造器管理实体类中的构造方法
public void test2() throws Exception {
// 1.获取class对象对象:三种方式
Class<Emps> c1 = Emps.class;
//2.获取构造方法的管理类
//2.1托管无参构造
Emps emps = c1.newInstance();
//2.2托管有参构造
Constructor<Emps> Constructor = c1.getDeclaredConstructor(Integer.class, String.class);
Emps emps1 = Constructor.newInstance(1, "元歌");
System.out.println(emps);
System.out.println(emps1);
}
普通方法
@Test//使用Method类,来管理实体类中的某个方法
public void test4() throws Exception {
// 1.获取class对象对象
Class<Emps> c1 = Emps.class;
//2.获取某个方法的管理类Method
Method method = c1.getDeclaredMethod("setName", String.class);
Emps emps = c1.newInstance();
System.out.println(emps);
method.invoke(emps,"韩信");
System.out.println(emps);
System.out.println("--------调用toString------");
Method method1 = c1.getDeclaredMethod("toString");
Object invoke = method1.invoke(emps);
System.out.println(invoke);
}
属性
@Test//使用field类,来管理实体类中的某个属性
public void test3() throws Exception {
// 1.获取class对象对象:三种方式
Class<Emps> c1 = Emps.class;
//2.获取某个属性的管理类Field
Field f1 = c1.getDeclaredField("name");
Field f2 = c1.getDeclaredField("age");
Emps emps = c1.newInstance();
//3.开启私有属性的操作权限
f1.setAccessible(true);
f2.setAccessible(true);
System.out.println(emps);
f1.set(emps,"孙尚香");
f2.set(emps,18);
System.out.println(emps);
}
反射案例
实现DBUtils工具类
封装查询结果集的原理
实用多个数据表格的通用查询
package com.web.jdbc;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
public class JdbcUtil {
//封装结果集的通用方法
public static <T> List<T> rsToList(String sql,Class<T> c){
ArrayList<T> list = new ArrayList<>();
//加载驱动,获取连接对象
try {
//加载驱动,获取连接对象
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/wuhanhb?useSSL=false", "root", "root");
//获取执行sql对象,执行sql,返回结果集rs
PreparedStatement psmt = con.prepareStatement(sql);
ResultSet rs = psmt.executeQuery(sql);
//3.遍历rs
//3.1借助元数据,获取列名和总列数
ResultSetMetaData md = rs.getMetaData();
int conut = md.getColumnCount();
while (rs.next()){
//循环一次获取一行数据,调用一次Object获取一个单元格的数据
T t = c.newInstance();
for (int i=1;i<=conut;i++) {
Object value = rs.getObject(i);
//每一列的列名充当T中的属性名,获取对应的属性管理对象f
Field f = c.getDeclaredField(md.getColumnName(i));
f.setAccessible(true);
//为私有属性赋值
f.set(t,value);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
测试代码
查询emps数据表
- 这是数据库中的数据
- 这是测试类代码(Emps实体类不单独贴出)
@Test
public void test5(){
//测试jdbc工具类
List<Emps> emps = JdbcUtil.rsToList("select * from emps", Emps.class);
System.out.println(emps);
}
- 查询结果
查询dept数据表
- 这是数据库中的数据
- 这是测试类代码(Emps实体类不单独贴出)
@Test
public void test5(){
//测试jdbc工具类
List<Dept> dept = JdbcUtil.rsToList("select * from dept", Dept.class);
System.out.println(dept);
}
D
- 查询结果
来源:oschina
链接:https://my.oschina.net/u/4302130/blog/4488792