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

  • 一、 什么是反射?
  • 二、反射能做什么?

一、 什么是反射?

用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

如果你是一个Android Developer,前辈们都会教导你尽量少用反射,效率太低,太慢。“射”嘛,射的太快就不好了,所以反射虽然慢点,但是偶尔射一下还是很”爽”的。

二、反射能做什么?

1、新建类的实例

我们知道所有的类都继承子顶级父类Object,而Object中有hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。我们这里就需要使用的Class对象,注意C是大写,我们可以通过一下方式来获取Class对象

1.Class.forName(“类名字符串”) (注意:类名字符串必须是全称,包名+类名)
2.类名.class
3.实例对象.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;
    }

}

这里需要注意一个坑,先来看一段代码

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。

今天反射就暂时讲到这里。其实反射的作用远不于此,这里只是使用了反射的冰山一角,结合注解和泛型,反射可以做的事更多,但是还是和开头讲的一样,反射用起来虽然很爽,但是不能乱射,和频繁的射,“射”的太多。“性”能会出问题!(o(∩_∩)o )。

Java高级特性之反射学习总结的更多相关文章

  1. Java高级特性之反射

    老规矩我们还是先提出几个问题,一门技术必然要能解决一定的问题,才有去学习掌握它的价值 一. 什么是反射? 二.反射能做什么? 一. 什么是反射? 用在Java身上指的是我们可以于运行时加载.探知.使用 ...

  2. Java高级特性之枚举学习总结

    在Java SE5之前,我们要使用枚举类型时,通常会使用static final 定义一组int常量来标识,代码如下 public static final int MAN = 0; public s ...

  3. Java高级特性——反射机制(第二篇)

    在Java高级特性——反射机制(第一篇)中,写了很多反射的实例,可能对于Class的了解还是有点迷糊,那么我们试着从内存角度去分析一下. Java内存 从上图可以看出,Java将内存分为堆.栈.方法区 ...

  4. java高级特性增强

    第4天 java高级特性增强 今天内容安排: 1.掌握多线程 2.掌握并发包下的队列 3.了解JMS 4.掌握JVM技术 5.掌握反射和动态代理 java多线程增强 .1. java多线程基本知识 . ...

  5. paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  6. Java高级特性-String、StringBuffer和StringBuilder

    Java高级特性-String.StringBuffer和StringBuilder String Java语言中的字符串值都属于String类,虽然有其他方法表示字符串(如字符串数组),但Java一 ...

  7. Java高级特性1_流库_初体验

    Java高级特性流库_初体验 面对结果编程 在编程里, 有两种编程方式, 一种是面对过程编程, 一种是面对结果编程. 两者区别如下 面向过程编程 面向过程编程需要编程程序让程序依次执行得到自己想要的结 ...

  8. Java高级语法之反射

    Java高级语法之反射 什么是反射 java.lang包提供java语言程序设计的基础类,在lang包下存在一个子包:reflect,与反射相关的APIs均在此处: 官方对reflect包的介绍如下: ...

  9. Java高级特性 第5节 序列化和、反射机制

    一.序列化 1.序列化概述 在实际开发中,经常需要将对象的信息保存到磁盘中便于检索,但通过前面输入输出流的方法逐一对对象的属性信息进行操作,很繁琐并容易出错,而序列化提供了轻松解决这个问题的快捷方法. ...

随机推荐

  1. OD: Windows Driver Fuzz

    内核 FUZZ 思路 内核 API  函数:是提供给 Ring3 调用,在 Ring0 完成最终功能的函数.这些函数接收 Ring3 传入的参数,如果处理参数的过程存在问题的话,很有可能成为一个内核漏 ...

  2. angular.bind

    angular.bind :Returns a function which calls function fn bound to self (self becomes the this for fn ...

  3. "SOAP WebService " 和 "RESTful WebService" 的定义分别是什么???

    一个个来,要知道区别,首先得知道各自的意义及用途web service采用Xml传输结构化的数据,轻量级跨平台而soap则是一种基于http的应用层通讯协议,同样采用xml编码,只不过soap又更进了 ...

  4. RESTful Web Services简单介绍

    近几年,RESTful Web Services渐渐开始流行,大量用于解决异构系统间的通信问题.很多网站和应用提供的API,都是基于RESTful风格的Web Services,比较著名的包括Twit ...

  5. iOS学习笔记(十四)——打电话、发短信

    电话.短信是手机的基础功能,iOS中提供了接口,让我们调用.这篇文章简单的介绍一下iOS的打电话.发短信在程序中怎么调用. 1.打电话 [[UIApplication sharedApplicatio ...

  6. CSP内容安全策略

    在浏览网页的过程中,尤其是移动端的网页,经常看到有很多无关的广告,其实大部分广告都是所在的网络劫持了网站响应的内容,并在其中植入了广告代码.为了防止这种情况发生,我们可以使用CSP来快速的阻止这种广告 ...

  7. centos U盘安装

    1.版本 LiveCD 和 LiveDVD 是可以直接进入运行系统,类似win PE, 进入系统后有一个图标 install - HHD(从硬盘安装). netinstall 是用于网络安装和系统救援 ...

  8. PHP json的插入和解析在数据库中的操作

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. PHP中往数据库中存储json数据在项目开发中也经常遇到,下面我就 ...

  9. Linux makefile 教程 非常详细,且易懂(转)

    转自:http://blog.chinaunix.net/uid-27717694-id-3696246.html 原文地址:Linux makefile 教程 非常详细,且易懂 作者:Deem_pa ...

  10. linux文件系统结构和权限

    linux文件系统的目录结构 熟话说的好,好记性不如烂笔头,虽然没用笔,但动动手指还是可以的.下面的目录结构都是摘抄过来的,动动手指来加深下印象吧,还能练习下打字速度,哈哈,多好啊. ...突然又改变 ...