美文网首页
Java反射机制-----反射基础

Java反射机制-----反射基础

作者: 文艺咖 | 来源:发表于2018-02-12 16:17 被阅读0次
封面图.jpg

前言

  接上两节,本想在本节介绍MVP和MVVM框架的搭建和实现原理。但是研究MVVM框架时发现,DataBinding作为其主要实现手段,包含后面将要涉及的Retrofit、butterknife、Gson与Fastjson等框架底层原理均由 动态代理注解 来实现的。而动态代理和注解的实现,其实质就是依靠 反射 来实现的。
  因此将会用几节来介绍java反射机制,包含动态代理以及注解(运行时和编译时)的使用,来为后面框架的介绍做好铺垫。

反射.PNG

指引

Java中创建对象的5种方式

  • 使用new关键字
  • 使用Class类的newInstance方法
  • 使用Constructor类的newInstance方法
  • 使用clone方法
  • 使用反序列化

往往我们创建一个类的对象,采取的最多的方式就是使用new关键字,其中第二种和第三种方式就是和反射有关。

  Class c = TestClassImpl.class;
  TestClassImpl t = (TestClassImpl) c1.newInstance();
  Constructor ct = TestClassImpl.class.getDeclaredConstructor();
  TestClassImpl t = (TestClassImpl) ct.newInstance();

反射的定义

  反射机制的定义是,在运行状态下,对于任意的类(或者对象)都可以获取任意一个属性和方法,并且可以调用它的任意一个方法和属性。
  关键词:运行时

正文

Class类的实例对象
java.lang.Class是所有类的类,Class类是了解反射的基础。
而Class类的构造函数,无法使用new关键字来创建

  private Class(ClassLoader loader) { 
      classLoader = loader; 
  }

但是我们可以通过已有的类(或者对象)来获取。

  //第一种
  Class c1 = TestClassImpl.class;
  //第二种
  Class c2 = Class.forName("com.qqj.test.proxy.TestClassImpl");
  //第三种
  TestClassImpl testClass = new TestClassImpl();
  Class c3 = testClass.getClass();

反射的相关操作

  • 获取成员方法Method
  • 获取成员变量Field
  • 获取构造函数Constructor
  • 获取成员方法Method
  1. 获取指定名称成员方法Method
  Method method = c1.getMethod("showMessage", Context.class);
  Object o = c1.newInstance();
  method.invoke(o, MainActivity.this);
  Method method = c1.getDeclaredMethod("showMessage", Context.class);
  Object o = c1.newInstance();
  method.invoke(o, MainActivity.this);
  1. 获取所有成员方法Method
  Method method = c1.getMethods()[0];
  Object o = c1.newInstance();
  method.invoke(o, MainActivity.this);
  Method method = c1.getDeclaredMethods()[0];
  Object o = c1.newInstance();
  method.invoke(o, MainActivity.this);

其中,getMethodgetMethods获取的是类的所有(或指定)共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有(或指定)public方法。getDeclaredMethodgetDeclaredMethods获取的是类自身声明的所有(或指定)方法,包含public、protected和private方法。

  • 获取成员变量Field
  1. 获取指定名称的成员变量Field
  Class c = MainActivity.class;
  Field field = c.getField("btn1");
  field.setAccessible(true);
  field.set(MainActivity.this, this.findViewById(R.id.btn1));
Class c = MainActivity.class;
Field field = c.getDeclaredField("btn1");
field.setAccessible(true);
field.set(MainActivity.this, this.findViewById(R.id.btn1));
  1. 获取所有成员变量Field
Class c = MainActivity.class;
Field field = c.getFields()[0];
field.setAccessible(true);
field.set(MainActivity.this, this.findViewById(R.id.btn1));
Class c = MainActivity.class;
Field field = c.getDeclaredFields()[0];
field.setAccessible(true);
field.set(MainActivity.this, this.findViewById(R.id.btn1));

其中,getFieldgetFields获取的是类的所有(或指定)共有成员变量,这就包括自身的所有public方法,和从基类继承的所有(或指定)public变量。getDeclaredFieldgetDeclaredFields获取的是类自身声明的所有(或指定)成员变量,包含public、protected和private方法。

  • 获取构造函数Constructor
  1. 获取指定参数的构造函数
Class c1 = TestClassImpl.class;
Constructor constructor = c1.getConstructor(String.class);
constructor.setAccessible(true);
constructor.newInstance("qqj");
Class c1 = TestClassImpl.class;
Constructor constructor = c1.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
constructor.newInstance("qqj");
  1. 获取所有构造函数
Class c1 = TestClassImpl.class;
Constructor constructor = c1.getConstructors()[0];
constructor.setAccessible(true);
constructor.newInstance("qqj");
Class c1 = TestClassImpl.class;
Constructor constructor = c1.getDeclaredConstructors()[0];
constructor.setAccessible(true);
constructor.newInstance("qqj");

区别:Class.newInstance只可以创建无参构造函数的实例,而Constructor.newInstance可以创建有参数和无参数构造函数的实例。

应用举例

  • Gson框架
  • Fastjson框架

1. Gson
  简介:是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,但自从在2008年五月公开发布第一版后已被许多公司或用户应用。
  添加依赖

  implementation 'com.google.code.gson:gson:2.2.4'

  JavaBean

  public class User {
    private String userIds;
    private String usernames;

    public String getUserId() {
        return userIds;
    }

    public void setUserId(String userId) {
        this.userIds = userId;
    }

    public String getUsername() {
        return usernames;
    }

    public void setUsername(String username) {
        this.usernames = username;
    }
}

  序列化

  Gson gson = new Gson();
  User user = new User();
  user.setUserId("9527");
  user.setUsername("qqj");
  String userJson = gson.toJson(user);
  Log.d("gsontest", userJson);
Gson序列化.PNG
  反序列化
  Gson gson = new Gson();
  String strJson = "{userIds:'9527', usernames:'qqj'}";
  User user = gson.fromJson(strJson, User.class);
Gson反序列化.PNG
2. Fastjson
  简介: Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。
  添加依赖
  implementation 'com.alibaba:fastjson:1.2.7'

  序列化

  User user = new User();
  user.setUserId("9527");
  user.setUsername("qqj");
  String userJson = JSON.toJSONString(user);
  Log.d("fastjsontest", userJson);
Fastjson序列化.PNG
  反序列化
  String strJson = "{userId:'9527', username:'qqj'}";
  User user = JSON.parseObject(strJson, User.class);
Fastjson反序列化.PNG
3. Gson和Fastjson原理对比
  无论是哪种解析方式,两者底层均由 反射 来实现。 对比.PNG

  Gson
  无论序列化还是反序列化,都与真实的类成员名有关。

  Fastjson
  1. 序列化(对象 to Json) 利用反射找到对象类的所有Get方法,然后把"get"去掉,小写化,作为Json的每个key值,如 getA 对应的key值为 a,而与真实的类成员名无关。
  2. 反序列化(Json to 对象)先同样通过反射找到对象类所有的Set方法,然后使用无参数构造函数(所以一定要有无参数的构造函数)新建一个类对象,从Json字符串中取出一个key 如 a,先大写化为A,那么从所有Set方法中找到 SetA(),然后进行赋值。 如果找不到 setA (seta也不行),那么该值被忽略,也不报错。

相关文章

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • Java中反射的用途

    Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对大家以后学习框...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • java反射机制

    java的反射机制 1 JAVA的反射机制是什么?反射机制能做什么?反射机制的优点与缺点2 认识 Class...

  • 反射之三

    总结内容源自以下文章 粗浅看java反射机制 反射机制应用实践 谈谈java反射机制 Java Reflectio...

  • Java反射机制-----反射基础

    前言   接上两节,本想在本节介绍MVP和MVVM框架的搭建和实现原理。但是研究MVVM框架时发现,DataBin...

  • 第6讲 | 动态代理是基于什么原理?

    谈谈 Java 反射机制,动态代理是基于什么原理? 典型回答 反射机制是 Java 语言提供的一种基础功能,赋予程...

  • JAVA反射机制知识

    导读 移动开发知识体系总章(Java基础、Android、Flutter) 反射机制的概念 反射机制的主要功能 与...

网友评论

      本文标题:Java反射机制-----反射基础

      本文链接:https://www.haomeiwen.com/subject/ktmgzxtx.html