
前言
接上两节,本想在本节介绍MVP和MVVM框架的搭建和实现原理。但是研究MVVM框架时发现,DataBinding作为其主要实现手段,包含后面将要涉及的Retrofit、butterknife、Gson与Fastjson等框架底层原理均由 动态代理 和 注解 来实现的。而动态代理和注解的实现,其实质就是依靠 反射 来实现的。
因此将会用几节来介绍java反射机制,包含动态代理以及注解(运行时和编译时)的使用,来为后面框架的介绍做好铺垫。
指引
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
- 获取指定名称成员方法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);
- 获取所有成员方法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);
其中,getMethod和getMethods获取的是类的所有(或指定)共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有(或指定)public方法。getDeclaredMethod和getDeclaredMethods获取的是类自身声明的所有(或指定)方法,包含public、protected和private方法。
- 获取成员变量Field
- 获取指定名称的成员变量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));
- 获取所有成员变量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));
其中,getField和getFields获取的是类的所有(或指定)共有成员变量,这就包括自身的所有public方法,和从基类继承的所有(或指定)public变量。getDeclaredField和getDeclaredFields获取的是类自身声明的所有(或指定)成员变量,包含public、protected和private方法。
- 获取构造函数Constructor
- 获取指定参数的构造函数
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");
- 获取所有构造函数
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 gson = new Gson();
String strJson = "{userIds:'9527', usernames:'qqj'}";
User user = gson.fromJson(strJson, User.class);
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);
反序列化
String strJson = "{userId:'9527', username:'qqj'}";
User user = JSON.parseObject(strJson, User.class);
3. Gson和Fastjson原理对比
无论是哪种解析方式,两者底层均由 反射 来实现。
Gson
无论序列化还是反序列化,都与真实的类成员名有关。
Fastjson
1. 序列化(对象 to Json) 利用反射找到对象类的所有Get方法,然后把"get"去掉,小写化,作为Json的每个key值,如 getA 对应的key值为 a,而与真实的类成员名无关。
2. 反序列化(Json to 对象)先同样通过反射找到对象类所有的Set方法,然后使用无参数构造函数(所以一定要有无参数的构造函数)新建一个类对象,从Json字符串中取出一个key 如 a,先大写化为A,那么从所有Set方法中找到 SetA(),然后进行赋值。 如果找不到 setA (seta也不行),那么该值被忽略,也不报错。
网友评论