Java高级特性之反射学习总结
作者:网络转载 发布时间:[ 2017/5/31 11:09:52 ] 推荐标签:测试开发技术 Java
老规矩我们还是先提出几个问题,一门技术必然要能解决一定的问题,才有去学习掌握它的价值
一、 什么是反射?
二、反射能做什么?
一、 什么是反射?
用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
如果你是一个Android Developer,前辈们都会教导你尽量少用反射,效率太低,太慢。“射”嘛,射的太快不好了,所以反射虽然慢点,但是偶尔射一下还是很”爽”的。
二、反射能做什么?
1、新建类的实例
我们知道所有的类都继承子父类Object,而Object中有hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。我们这里需要使用的Class对象,注意C是大写,我们可以通过一下方式来获取Class对象
Class.forName(“类名字符串”) (注意:类名字符串必须是全称,包名+类名)
类名.class
实例对象.getClass()
在Class类中有一个非常重要的方法
public T newInstance() throws InstantiationException, IllegalAccessException {
return newInstanceImpl();
}
private native T newInstanceImpl() throws IllegalAccessException, InstantiationException;
查看Api可以看到调用newInstace方法可以返回当前class对应的实例对象。接下来看一个小的Demo
public class Reflection {
public static void main(String[] args) {
// 普通创建类的实例
People p1 = new People();
System.out.println(p1.getName());
// 利用反射获取类的实例
Class clazz = People.class;
// 常用方式,注意括号中需要放类的全路径名
// Class clazz = Class.forName("reflection.People");
// Class clazz = p1.getClass();
try {
People p2 = (People) clazz.newInstance();
System.out.println(p2.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class People {
private String name = "张三";
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
输入结果:
张三
张三
2、获取成员变量和方法
在讲之前我们先来看这样一个小按理,JSON数据转JavaBaen对象,在不用解析库的情况下,一般我们会这样做
private void analysisDate(JSONObject response) throws JSONException {
int announceid = response.getInt("announceid");
String title = response.getString("title");
String hits = response.getString("hits");
String addtime = response.getString("addtime");
NewsNotifyItem newsNotifyItem = new NewsNotifyItem(announceid,
title, hits, addtime);
}
}
每当我们需要解析额时候,都需要根据不同javabean来进行相应的解析,我们每次进行的操作都是一样的,只是解析的数据不同而已,结合上篇帖子讲到的泛型,这里我们可以再利用反射来自己做一个Json解析工具。
下面是我写的一个JsonObject对象转JavaBean的一个工具类,需要注意的是,JSON的key需要和字段名保持一致,先说下思路
①首先通过反射获取JavaBean中的所有字段值的名称
②拼接出set方法
③由于字段名和Json的key值相同,利用自动名获取Json中的值并填充的实例对象中
public class Json2BeanUtils {
public static <T> T jsonToBean(JSONObject response, Class<T> clazz) {
try {
// 创建类的实例
Object object = Class.forName(clazz.getName()).newInstance();
// 获取类中的所有成员变量
Field[] fields = object.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
//设置权限
fields[i].setAccessible(true);
// 获取字段的名称
String fieldName = fields[i].getName();
// 过滤掉UID
if (fieldName.endsWith("serialVersionUID")) {
continue;
}
// 获取字段的类型
String fieldType = fields[i].getGenericType().toString();
// 拼接出JavaBean中的set方法 这里有一个坑 后面讲解
String methodName = "set"
+ fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
try {
// 判断变量类型
if (fieldType.endsWith("class java.lang.String")) {
// 获取到set方法
Method m = object.getClass().getMethod(methodName,
String.class);
String value = null;
try {
// 从JsonObj中取出相应的值
value = response.getString(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = "";
}
if (TextUtils.isEmpty(value)) {
value = "";
} else if (value.endsWith("null")) {
value = "";
}
// 赋值
m.invoke(object, value);
} else if (fieldType.endsWith("int")
|| fieldType.endsWith("class java.lang.Integer")) {
// int 类型
System.out.println();
Method m = object.getClass().getMethod(methodName,
int.class);
int value = -1;
try {
value = response.getInt(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = -1;
}
m.invoke(object, value);
} else if (fieldType.endsWith("boolean")
|| fieldType
.endsWith("fieldType:class java.lang.Boolean")) {
// boolean 类型
Method m = object.getClass().getMethod(methodName,
boolean.class);
boolean value = false;
try {
value = response.getBoolean(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = false;
}
m.invoke(object, value);
} else if (fieldType.endsWith("double")
|| fieldType
.endsWith("fieldType:class java.lang.Double")) {
// double 类型
Method m = object.getClass().getMethod(methodName,
double.class);
double value = -1D;
try {
value = response.getDouble(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = -1D;
}
m.invoke(object, value);
} else if (fieldType.endsWith("char")) {
// char类型 JSONObject 没有char
Method m = object.getClass().getMethod(methodName,
String.class);
String value = "";
try {
value = response.getString(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = "";
}
m.invoke(object, value);
} else if (fieldType.endsWith("float")
|| fieldType
.endsWith("fieldType:class java.lang.Float")) {
// float类型
Method m = object.getClass().getMethod(methodName,
double.class);
double value = -1D;
try {
value = response.getDouble(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = -1D;
}
m.invoke(object, value);
} else if (fieldType.endsWith("short")
|| fieldType
.endsWith("fieldType:class java.lang.Short")) {
// short
Method m = object.getClass().getMethod(methodName,
short.class);
int value = -1;
try {
value = response.getInt(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = -1;
}
m.invoke(object, value);
} else if (fieldType.endsWith("byte")
|| fieldType
.endsWith("fieldType:class java.lang.Byte")) {
Method m = object.getClass().getMethod(methodName,
byte.class);
int value = -1;
try {
value = response.getInt(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = -1;
}
m.invoke(object, value);
} else if (fieldType.endsWith("long")
|| fieldType
.endsWith("fieldType:class java.lang.Long")) {
Method m = object.getClass().getMethod(methodName,
long.class);
Long value = -1L;
try {
value = response.getLong(fieldName);
} catch (Exception e) {
e.printStackTrace();
value = -1L;
}
m.invoke(object, value);
}
} catch (Exception e) {
// TODO: handle exception
}
}
return (T) object;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11