老规矩我们还是先提出几个问题,一门技术必然要能解决一定的问题,才有去学习掌握它的价值

东辽ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:13518219792(备注:SSL证书合作)期待与您的合作!
一、 什么是反射?
用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得老牌称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
如果你是一个Android Developer,前辈们都会教导你尽量少用反射,效率太低,太慢。“射”嘛,射的太快就不好了,所以反射虽然慢点,但是偶尔射一下还是很”爽”的。
二、反射能做什么?
1、新建类的实例
我们知道所有的类都继承子***父类Object,而Object中有hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。我们这里就需要使用的Class对象,注意C是大写,我们可以通过一下方式来获取Class对象
在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 jsonToBean(JSONObject response, Class 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;
 - }
 - }
 
这里需要注意一个坑,先来看一段代码
- class People {
 - private String name;
 - private int age;
 - private String mSex;
 - 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;
 - }
 - public String getmSex() {
 - return mSex;
 - }
 - // 这里就出了问题
 - public void setmSex(String mSex) {
 - this.mSex = mSex;
 - }
 - }
 
当我们自动生成get set方法时,会将字段的首字母大写,我们在上面拼接set 方法时,也是基于这样的规则来拼装的。但是 当我们的字段名为 aAbbb 时,则生成的get set 方法则不会大写。解决方案也很简单,注意字段命名或者在拼接时对第二个自动进行大小写判断。这样我们自己写的Json解析工具就搞定, 以后每次解析只需一行代码即可OK。
                新闻名称:Java高级特性之反射学习总结
                
                当前链接:http://www.csdahua.cn/qtweb/news45/19745.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网