Java对泛型进行反射实战
一、概述
前两节接连介绍了,Java的反射技术,以及把Java的反射技术封装成类库。本节接下来介绍的内容都是基于以上两节来实现的。如果读者看起来吃力可以回过头看看前两节的内容,然后接着看本节内容。
二、实战
整体流程描述:首先先定义一个泛型的单例类Singleton,然后在BookManger中实例化这个单例。IBook是一个接口。JavaBook和AndroidBook是IBook的具体实现类。ReflectUtil是反射工具类
在BookManger中默认单例返回的是JavaBook。我们通过反射将其动态替换为默认返回AndroidBook。
1.IBook.java
1 2 3 4 5 6 7 8 9 10 11 | package com.yw.reflectjavalib.generic; /** * book接口 * create by yangwei * on 2020-02-07 16:59 */ public interface IBook { void write(); void read(); } |
2.JavaBook.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package com.yw.reflectjavalib.generic; /** * create by yangwei * on 2020-02-07 17:04 */ public class JavaBook implements IBook { @Override public void write() { System.out.println( "正在写java代码" ); } @Override public void read() { System.out.println( "正在读java代码" ); } } |
3.AndroidBook.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.yw.reflectjavalib.generic; import com.yw.reflectjavalib.LogUtil; /** * create by yangwei * on 2020-02-07 17:07 */ public class AndroidBook implements IBook { @Override public void write() { LogUtil.e( "正在写Android" ); } @Override public void read() { LogUtil.e( "正在阅读Android" ); } } |
4.BookManger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.yw.reflectjavalib.generic; /** * book的管理类 * create by yangwei * on 2020-02-07 17:03 */ public class BookManager { private static final Singleton<IBook> getDefault = new Singleton<IBook>() { @Override protected IBook create() { return new JavaBook(); } }; public static IBook getDefault() { return getDefault.get(); } } |
5.Singleton
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.yw.reflectjavalib.generic; /** * 泛型单例 * create by yangwei * on 2020-02-07 17:00 */ public abstract class Singleton<T> { private T mInstance; protected abstract T create(); public final T get() { synchronized ( this ) { if (mInstance == null ) { mInstance = create(); } } return mInstance; } } |
6.ReflectGenericDemo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package com.yw.reflectjavalib.generic; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Proxy; /** * 对泛型进行反射 * <p> * 通过动态代理模式+反射把JavaBook替换成我们需要的AndroidBook。对BookManager进行代码注入 * create by yangwei * on 2020-02-07 16:58 */ public class ReflectGenericDemo { public static void main(String[] args) throws Exception { //获取Singleton的mInstance字段 Class<?> singleton = Class.forName( "com.yw.reflectjavalib.generic.Singleton" ); Field mInstanceField = singleton.getDeclaredField( "mInstance" ); mInstanceField.setAccessible( true ); //获取bookmanager的getDefault字段 Class<?> bookManager = Class.forName( "com.yw.reflectjavalib.generic.BookManager" ); Field getDefaultField = bookManager.getDeclaredField( "getDefault" ); getDefaultField.setAccessible( true ); //获取gedefault字段的值,其实就是Singleton实例 Object getDefault = getDefaultField.get( null ); //把JavaBook替换为AndroidBook mInstanceField.set(getDefault, new AndroidBook()); BookManager.getDefault().read(); } } |
运行BookManger.getDefault().read()方法,我们发现打印出来的确实是“正在阅读Android”,如果把mInstanceFiled.set(getDefault,new AndroidBook)注释掉,则输出的是“正在阅读Java”。这种情况也可称之为Hook,利用这种技术我们可以做一些底层类的替换(android插件化相关)。例如:我们可以对AMS和PMS进行hook。或者对Instrumentation或者mCallback进行hook。
下一节将讲解动态代理,也是基于反射,比这一节的内容更为高级一点。一遍我们在做插件话hook的时候通常会用到proxy.newProxyInstance.敬请期待
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库