1310 字
7 分钟
Java反射机制

Java反射机制#

反射的概念#

在运行时加载、探知、使用编译期间完全未知的classes

加载类#

Class类#

所有加载的类也是一个对象,这些对象共有的行为特征抽象为Class类,加载的类就是一个一个的Class对象

如何获得Class对象#

  1. Class.forName(“包名.类型”) :
//获得Person类的类对象
try {
Class cls = Class.forName("com.hyxy.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

使用场景: 编译环境中没有Person类时

  1. 类名.class : 编译的字节码文件中,默认有一个静态的class属性,存储了这个类的对象
//获得Person类的类对象
Class cls = Person.class;

使用场景:编译环境中有Person类,最直接的方式

  1. 对象.getClass方法
//获得Person类的类对象
Person p = new Person();
Class cls = p.getClass();

使用场景:编译环境中有类,现在持有一个对象,但是不知道这个对象的类型,要获得这个对象的类对象

public static void method(Object obj){
//获得参数obj的类对象
Class cls = obj.getClass();
}

Class类的方法#

  1. getName方法 : 包名+类名
  2. getSimpleName方法: 获取类名
  3. newInstance方法:创建类对象对应类的对象,这个方法实质还是调用了类无参构造器,已过时(后续要获得构造器对象来创建对象)
  4. getDeclaredField(String name) :通过名字获得属性对象
  5. getDeclaredFields : 获得所有属性,得到的是属性数组(Field[])
  6. getDeclaredMethod(String methodName,Class … parameterType) : 通过方法名和参数类型列表获得一个方法对象
  7. getDeclaredConstructor(Class … parameterType) : 通过参数类型列表获得一个构造器

Field类#

每个Field对象就是类中的某个属性的实例,Field对象中包含属性名、属性类型、属性值的属性

对属性的操作包括 : 对象属性的赋值和取值操作

方法:

  1. 设置属性可访问: setAccessable
  2. 设置对象的属性值: set(Object obj,Object value)
  3. 获取对象的属性值: get(Object obj)

实例:获取学生类的姓名、年龄、序号三个属性对象,对某个学生对象的三个属性复制、获取某个学生对象的三个属性值

package com.hyxy;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
try {
//Student的类对象
Class stuCls = Class.forName("com.hyxy.Student");
//创建一个Student对象
Object obj = stuCls.newInstance();
//通过属性名获取三个属性对象
Field fleld1 = stuCls.getDeclaredField("name");
Field fleld2 = stuCls.getDeclaredField("age");
Field fleld3 = stuCls.getDeclaredField("no");
//设置这个属性是可访问
fleld1.setAccessible(true);
//为obj对象(Student对象)的name属性赋值为tom
fleld1.set(obj,"tom");
System.out.println(fleld1.get(obj));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}

Method类#

每个对象代表了类中一个一个方法实例,对方法的操作主要是执行方法

方法:

invoke方法: 执行方法,需要传入实参

public class Test {
public static void main(String[] args) {
try {
//Student的类对象
Class stuCls = Class.forName("com.hyxy.Student");
//创建一个Student对象
Object obj = stuCls.newInstance();
//获得student对象的study()方法
Method method1 = stuCls.getDeclaredMethod("study");
//获得student对象的study(String lession,int time)方法
Method method2 = stuCls.getDeclaredMethod("study",String.class,int.class);
//获得student对象的study(int time,String lession)方法
Method method3 = stuCls.getDeclaredMethod("study",int.class,String.class);
//执行method1方法
method1.invoke(obj);
//执行method2方法,传入的字符串是"abc",传入的时间是24
method2.invoke(obj,"abc",24);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

Constructor构造器#

方法:

newInstance方法: 调用构造器创建对象,需要传入实参

实例:

public class Test {
public static void main(String[] args) {
try {
//Student的类对象
Class stuCls = Class.forName("com.hyxy.Student");
//获得构造器
Constructor constructor = stuCls.getDeclaredConstructor(String.class,int.class,int.class);
Object obj = constructor.newInstance("tom",20,110011);
Student student = (Student)obj;
System.out.println(student.getName()+","+student.getAge()+","+student.getNo());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

反射实现通用DAO的二层封装#

DAO的二层封装:每个表都要写一个对应的DAO,原因是每个表的SQL语句是不同的,那么通过反射技术,将VO对象的类名作为表名、属性名作为列表,就可以动态的拼出每个表的SQL语句了,通过反射就可以用一个DAO实现SQL语句的封装,在通用DAO中要完成的事情:

  1. 获得VO参数的类对象
  2. 获得VO参数对象的类名和所有属性名
  3. 拼写SQL语句
  4. 使用JDBC执行SQL语句

实现DAO:

package com.hyxy.dao;
import com.hyxy.vo.T_User;
import org.apache.commons.dbutils.QueryRunner;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class CommonDao {
public int insert(Object obj,String pkName,boolean isAutoIncre){
Class cls = obj.getClass();
//类名作为表名
String tableName = cls.getSimpleName();
String columnJoinStr = "";
String wenhaoJoinStr = "";
Field[] flelds = cls.getDeclaredFields();
List<String> columnNameList = new ArrayList<>();
List<String> wenhaoList = new ArrayList<>();
List<Object> valueList = new ArrayList<>();
String[] names = new String[columnNameList.size()];
for(Field fleld:flelds){
fleld.setAccessible(true);
columnNameList.add(fleld.getName());
if(fleld.getName().equals(pkName)&&isAutoIncre){
wenhaoList.add("default");
}else{
wenhaoList.add("?");
try {
valueList.add(fleld.get(obj));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
columnJoinStr = String.join(",",columnNameList.toArray(names));
wenhaoJoinStr = String.join(",",wenhaoList.toArray(new String[wenhaoList.size()]));
String sql = "insert into "+tableName+"("+columnJoinStr+") " +
"values("+wenhaoJoinStr+")";
System.out.println(sql);
Connection conn = DBUtil.getConnection();
QueryRunner queryRunner = new QueryRunner();
int result = 0;
try {
result = queryRunner.execute(conn,sql,valueList.toArray());
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
public int update(Object obj,String pkName){
return 0;
}
public int delete(Class cls,String pkName,Object pkValue){
return 0;
}
public Object queryById(Class cls,String pkName,Object pkValue){
return null;
}
public List<Object> query(Class cls, Map<String,Object> map){
return null;
}
public static void main(String[] args) {
CommonDao commonDao = new CommonDao();
T_User user = new T_User();
user.setUsername("test123");
user.setPwd("123456");
user.setEmail("4324342@qq.com");
commonDao.insert(user,"id",true);
}
}
Java反射机制
https://mizuki.mysqil.com/posts/4反射/
作者
SuifengFlying
发布于
2026-07-28
许可协议
CC BY-NC-SA 4.0

MySQL基础

4 / 5

Related articles

部分信息可能已经过时

封面
示例歌曲
示例艺术家
封面
示例歌曲
示例艺术家
0:00 / 0:00