阿哲学了就来聊——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对象
1
2
3
4
5
6
7
8
9
10
11
12
@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.分别对实体类的成员(属性,方法,构造方法)进行托管
}

构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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);
}

普通方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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);

}

属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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工具类

封装查询结果集的原理
实用多个数据表格的通用查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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实体类不单独贴出)

    1
    2
    3
    4
    5
    6
    @Test
    public void test5(){
    //测试jdbc工具类
    List<Emps> emps = JdbcUtil.rsToList("select * from emps", Emps.class);
    System.out.println(emps);
    }
  • 查询结果
    查询emps表

    查询dept数据表

  • 这是数据库中的数据
    dept数据

  • 这是测试类代码(Emps实体类不单独贴出)

    1
    2
    3
    4
    5
    6
    @Test
    public void test5(){
    //测试jdbc工具类
    List<Dept> dept = JdbcUtil.rsToList("select * from dept", Dept.class);
    System.out.println(dept);
    }

    D

  • 查询结果
    dept表查询结果

源码

点击获取源码

文章目录
  1. 1. 概念
    1. 1.1. Class类
      1. 1.1.1. 获得类的相关方法
      2. 1.1.2. 获得类中属性相关的方法
      3. 1.1.3. 获得类中构造器的相关方法
    2. 1.2. Field
    3. 1.3. Method类
    4. 1.4. Constructor类
  2. 2. 作用
    1. 2.1. 构造方法
    2. 2.2. 普通方法
    3. 2.3. 属性
  3. 3. 反射案例
    1. 3.1. 实现DBUtils工具类
    2. 3.2. 测试代码
      1. 3.2.1. 查询emps数据表
      2. 3.2.2. 查询dept数据表
  4. 4. 源码
,