网站首页 > 精选教程 正文
Java反射
说到Java中的反射使用,大家肯定不陌生,但是在真正使用的时候却犯了难。因为不经常使用的关系,当真正需要使用反射的时候却经常忘记该怎么写了,真的是非常尴尬...
为此,我特地分类整理了一些常用的反射使用方法,以方便大家使用。
项目地址: https://github.com/xuexiangjys/architect-java/tree/master/src/basic/reflection
反射设置属性
反射设置某个对象的成员属性
/**
* 反射设置某个对象的成员属性
*
* @param owner 对象
* @param fieldName 属性名
* @param value 属性值
* @return
* @throws Exception
*/
public static void setField(Object owner, String fieldName, Object value)
throws Exception {
Class<?> ownerClass = owner.getClass();
Field field = ownerClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(owner, value);
}
反射设置某个类的静态属性
/**
* 反射设置某个类的静态属性
*
* @param className 类名
* @param fieldName 属性名
* @param value 属性值
* @return
* @throws Exception
*/
public static void setStaticField(String className, String fieldName, Object value)
throws Exception {
Class<?> ownerClass = Class.forName(className);
Field field = ownerClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, value);
}
/**
* 反射设置某个类的静态属性
*
* @param clazz 类
* @param fieldName 属性名
* @param value 属性值
* @return
* @throws Exception
*/
public static void setStaticField(Class<?> clazz, String fieldName, Object value)
throws Exception {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, value);
}
反射获取属性
反射获取某个对象的成员属性
/**
* 反射获取某个对象的成员属性
*
* @param owner 对象
* @param fieldName 属性名
* @return
* @throws Exception
*/
public static Object getField(Object owner, String fieldName)
throws Exception {
Class<?> ownerClass = owner.getClass();
Field field = ownerClass.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(owner);
}
反射获取某个类的静态属性
/**
* 反射获取某个类的静态属性
*
* @param className 类名
* @param fieldName 属性名
* @return
* @throws Exception
*/
public static Object getStaticField(String className, String fieldName)
throws Exception {
Class<?> ownerClass = Class.forName(className);
Field field = ownerClass.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(ownerClass);
}
/**
* 反射获取某个类的静态属性
*
* @param clazz 类
* @param fieldName 属性名
* @return
* @throws Exception
*/
public static Object getStaticField(Class<?> clazz, String fieldName)
throws Exception {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(clazz);
}
反射执行方法
注意点
- 对于我们封装的方法来说,当方法的参数类型是int、boolean、short等基础类型时,使用getClass()方法获取到的类型将是Integer、Boolean、Short等包装类,在调用getDeclaredMethod获取方法对象的时候就会抛异常NoSuchMethodException;
- 如果调用的方法属于该对象的父类,那getDeclaredMethod就会抛异常NoSuchMethodException;
获取参数的类集合方法
/**
* 获取参数的类集合
*
* @param args
* @return
*/
private static Class<?>[] getClasses(Object... args) {
Class<?>[] argsClass;
if (args != null && args.length > 0) {
argsClass = new Class[args.length];
for (int i = 0, j = args.length; i < j; i++) {
argsClass[i] = args[i].getClass();
}
} else {
argsClass = new Class[0];
}
return argsClass;
}
反射执行某对象的成员方法
/**
* 反射执行某对象的成员方法
*
* @param owner 对象
* @param methodName 方法名
* @param args 参数集合
* @return
* @throws Exception
*/
public static Object invokeMethod(Object owner, String methodName,
Object... args) throws Exception {
Class<?> ownerClass = owner.getClass();
Class<?>[] argsClass = getClasses(args);
Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
method.setAccessible(true);
return method.invoke(owner, args);
}
/**
* 反射执行某对象的成员方法(对于参数是基础类型的方法,反射时用getClass获取的是包装类型,会出错)
*
* @param owner 对象
* @param methodName 方法名
* @param args 参数集合
* @return
* @throws Exception
*/
public static Object invokeMethod(Object owner, String methodName,
Class<?>[] argsClass, Object... args) throws Exception {
Class<?> ownerClass = owner.getClass();
Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
method.setAccessible(true);
return method.invoke(owner, args);
}
反射执行某个类的静态方法
/**
* 反射执行某个类的静态方法
*
* @param className 类名
* @param methodName 方法名
* @param args 参数集合
* @return
* @throws Exception
*/
public static Object invokeStaticMethod(String className,
String methodName, Object... args) throws Exception {
Class<?> ownerClass = Class.forName(className);
Class<?>[] argsClass = getClasses(args);
Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
method.setAccessible(true);
return method.invoke(null, args);
}
/**
* 反射执行某个类的静态方法
*
* @param clazz 类
* @param methodName 方法名
* @param args 参数集合
* @return
* @throws Exception
*/
public static Object invokeStaticMethod(Class<?> clazz,
String methodName, Object... args) throws Exception {
Class<?>[] argsClass = getClasses(args);
Method method = clazz.getDeclaredMethod(methodName, argsClass);
method.setAccessible(true);
return method.invoke(null, args);
}
/**
* 反射执行某个类的静态方法(对于参数是基础类型的方法,反射时用getClass获取的是包装类型,会出错)
*
* @param className 类名
* @param methodName 方法名
* @param argsClass 参数类型的集合
* @param args 参数集合
* @return
* @throws Exception
*/
public static Object invokeStaticMethod(String className,
String methodName, Class<?>[] argsClass, Object... args) throws Exception {
Class<?> ownerClass = Class.forName(className);
Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
method.setAccessible(true);
return method.invoke(null, args);
}
/**
* 反射执行某个类的静态方法(对于参数是基础类型的方法,反射时用getClass获取的是包装类型,会出错)
*
* @param clazz 类
* @param methodName 方法名
* @param argsClass 参数类型的集合
* @param args 参数集合
* @return
* @throws Exception
*/
public static Object invokeStaticMethod(Class<?> clazz,
String methodName, Class<?>[] argsClass, Object... args) throws Exception {
Method method = clazz.getDeclaredMethod(methodName, argsClass);
method.setAccessible(true);
return method.invoke(null, args);
}
反射构建实例
/**
* 反射构建实例
*
* @param className 类名
* @param args 构造函数的参数集合
* @return
* @throws Exception
*/
public static Object newInstance(String className, Object... args)
throws Exception {
Class<?> newOneClass = Class.forName(className);
Class<?>[] argsClass = getClasses(args);
Constructor<?> cons = newOneClass.getDeclaredConstructor(argsClass);
cons.setAccessible(true);
return cons.newInstance(args);
}
/**
* 反射构建实例
*
* @param clazz 类
* @param args 构造函数的参数集合
* @return
* @throws Exception
*/
public static <T> T newInstance(Class<T> clazz, Object... args)
throws Exception {
Class<?>[] argsClass = getClasses(args);
Constructor<?> cons = clazz.getDeclaredConstructor(argsClass);
cons.setAccessible(true);
return (T) cons.newInstance(args);
}
/**
* 反射构建实例(对于参数是基础类型的方法,反射时用getClass获取的是包装类型,会出错)
*
* @param className 类名
* @param argsClass 参数类型的集合
* @param args 构造函数的参数集合
* @return
* @throws Exception
*/
public static Object newInstance(String className, Class<?>[] argsClass, Object... args)
throws Exception {
Class<?> newOneClass = Class.forName(className);
Constructor<?> cons = newOneClass.getDeclaredConstructor(argsClass);
cons.setAccessible(true);
return cons.newInstance(args);
}
/**
* 反射构建实例(对于参数是基础类型的方法,反射时用getClass获取的是包装类型,会出错)
*
* @param clazz 类
* @param argsClass 参数类型的集合
* @param args 构造函数的参数集合
* @return
* @throws Exception
*/
public static <T> T newInstance(Class<T> clazz, Class<?>[] argsClass, Object... args)
throws Exception {
Constructor<?> cons = clazz.getDeclaredConstructor(argsClass);
cons.setAccessible(true);
return (T) cons.newInstance(args);
}
测试
测试所需的类
/**
* 学生类
*
* @author xuexiang
* @since 2019/3/4 下午8:36
*/
public class Student {
/**
* 用于测试反射获取静态属性
*/
private static long TotalNumber = 28;
public int ID;
/**
* 用于测试反射获取成员属性
*/
private String Name;
private int Age = 20;
private int Sex;
private int Score;
private Student() {
}
/**
* 用于测试反射构建实例
*/
private Student(int ID, String name) {
this.ID = ID;
Name = name;
}
public Student(int ID, String name, int age) {
this.ID = ID;
Name = name;
Age = age;
}
public Student(int ID, String name, int age, int sex, int score) {
this.ID = ID;
Name = name;
Age = age;
Sex = sex;
Score = score;
}
/**
* 用于测试反射调用成员方法
* @return
*/
private String getName(Integer param) {
return Name;
}
/**
* 用于测试反射调用成员方法
* @return
*/
private Student setName(String name) {
Name = name;
return this;
}
/**
* 用于测试反射调用静态方法
* @return
*/
private static long incrementTotalNumber(int number) {
return TotalNumber + number;
}
@Override
public String toString() {
return "Student{" +
"ID=" + ID +
", Name='" + Name + '\'' +
", Age=" + Age +
", Sex=" + Sex +
", Score=" + Score +
"}, TotalNumber=" + TotalNumber;
}
}
/**
* 继承了Student,用于测试"如果调用的方法属于该对象的父类,那getDeclaredMethod就会抛异常NoSuchMethodException"的问题
*
* @author xuexiang
* @since 2019/3/4 下午10:12
*/
public class GoodStudent extends Student {
private int AchievementCount = 3;
public GoodStudent(int ID, String name, int age, int sex, int score) {
super(ID, name, age, sex, score);
}
public GoodStudent(Student student) {
super(student.ID + 1, "xxxx", 22);
}
public int getAchievementCount() {
return AchievementCount;
}
public GoodStudent setAchievementCount(int achievementCount) {
AchievementCount = achievementCount;
return this;
}
}
测试方法
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
Student student = new Student(123, "xxxxxx", 25, 0, 100);
System.out.println(student);
System.out.println("--------测试反射属性设置------------");
//反射设置某个对象的成员属性
try {
ReflectionUtils.setField(student, "Name", "xuexiang");
} catch (Exception e) {
e.printStackTrace();
}
//反射设置某个对象的静态属性
try {
ReflectionUtils.setStaticField(Student.class, "TotalNumber", 1111);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("--------测试反射属性获取------------");
//反射获取某个对象的成员属性
try {
System.out.println("Name:" + ReflectionUtils.getField(student, "Name"));
} catch (Exception e) {
e.printStackTrace();
}
//反射获取某个对象的静态属性
try {
System.out.println("TotalNumber:" + ReflectionUtils.getStaticField(Student.class, "TotalNumber"));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("--------测试反射方法执行------------");
//反射执行某对象的成员方法
try {
System.out.println("getName():" + ReflectionUtils.invokeMethod(student, "getName", 23));
} catch (Exception e) {
e.printStackTrace();
}
// //反射执行某对象父类的成员方法(将会出错)
// try {
// GoodStudent goodStudent = new GoodStudent(student);
// System.out.println("getName():" + ReflectionUtils.invokeMethod(goodStudent, "getName", 23));
// } catch (Exception e) {
// e.printStackTrace();
// }
//反射执行某个类的静态方法
try {
//对于参数是基础类型的方法,反射时用getClass获取的是包装类型,所以需要传入参数的类数组
System.out.println("incrementTotalNumber():" + ReflectionUtils.invokeStaticMethod(Student.class, "incrementTotalNumber", new Class[]{int.class}, 2));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("--------测试反射构建实例------------");
//反射构建实例
try {
Student student1 = ReflectionUtils.newInstance(Student.class, new Class[]{int.class, String.class}, 22334455, "xuexiangjys");
System.out.println(student1);
} catch (Exception e) {
e.printStackTrace();
}
// //反射父类的构造方法构建实例(将会出错)
// try {
// GoodStudent student2 = ReflectionUtils.newInstance(GoodStudent.class, new Class[]{int.class, String.class}, 22334455, "xuexiangjys");
// System.out.println(student2);
// } catch (Exception e) {
// e.printStackTrace();
// }
}
我是xuexiangjys,一枚热爱学习,爱好编程,勤于思考,致力于Android架构研究以及开源项目经验分享的技术up主。获取更多资讯,欢迎微信搜索公众号:【我的Android开源之旅】
- 上一篇: Java反射是什么?相信你看这篇绝对会了
- 下一篇: Java中的反射 java中的反射机制是指
猜你喜欢
- 2024-11-13 十年Java工程师写下的Java反射使用总结
- 2024-11-13 一起来了解Java中的反射 java反射的步骤原理
- 2024-11-13 Java基础:反射机制,你用得多吗 java反射机制有什么用
- 2024-11-13 每日一点涨薪小知识-JAVA反射 java反射的理解
- 2024-11-13 不是吧,还有人连Java最强大的技术之一:反射还没搞懂?赶紧码住
- 2024-11-13 Java反射的原理以及应用场景 java中反射的实际用法
- 2024-11-13 浅谈java中的反射(恭喜FPX) java里的反射是什么
- 2024-11-13 实操讲解Java的反射机制,你要是再看不懂,神仙都没救了
- 2024-11-13 两分钟学会Java反射 java 反射
- 2024-11-13 三石说:java基础 之 反射 java反射的基石
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)