红橙Darren视频笔记 反射注解泛型简介
1. 反射
作用:能够做一般做不到的事情,即获取私有方法 变量 构造方法 或者调用添加@hide的方法。比如XUtil的IOC( https://blog.csdn.net/u011109881/article/details/113762180 ),获取其他应用的资源文件( https://blog.csdn.net/u011109881/article/details/115558620 )都可以通过反射做到
所有的反射功能都是基于我们字节码(class),一个类的 class 在内存中应该只有一份,而且 class 其实也是一个Class对象
每个Class大致有以下3个部分
构造方法(Constructor) 方法(Method) 属性/域(Filed)
下面我们的例子按照如下顺序学习反射
1 反射调用构造方法
1.1 直接调用newInstance创建对象
1.2 调用getDeclaredConstructor来创建对象
1.3获取带参数的构造方法构建的对象
2 反射调用filed
3 反射调用method
3.1 调用无参方法
4 反射调用hide的方法或类
首先构建一个测试类
public class ReflectTestClass {private static final String TAG = "ReflectTestClass";private String mName = "hjcai";// public ReflectTestClass() {
// }private ReflectTestClass() {Log.e(TAG, "Constructor without parameters is called");}private ReflectTestClass(String name) {mName = name;Log.e(TAG, "Constructor with parameter String called");}private String getName() {Log.e(TAG, "getName: " + mName);return mName;}private void setName(String mName) {this.mName = mName;Log.e(TAG, "setName: " + mName);}
}
反射调用的类
public class MainActivity extends AppCompatActivity {private static final String TAG = "MyActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);testReflect();}private void testReflect() {Log.e(TAG, "testReflect: start ======>");getPrivateConstructor();Log.e(TAG, "testReflect: end ======>");getPrivateField();Log.e(TAG, "getPrivateMethod: start ======>");getPrivateMethod();Log.e(TAG, "getPrivateMethod: end ======>");getHideMethod();}// 1 反射调用构造方法private void getPrivateConstructor() {try {// 1.1 直接调用newInstance创建对象// 只能获取无参 public 的构造方法来构建对象 如果没有无参构造方法 则抛出异常ReflectTestClass reflectTestClassObj = ReflectTestClass.class.newInstance();} catch (IllegalAccessException | InstantiationException e) {e.printStackTrace();}try {// 1.2 调用getDeclaredConstructor来创建对象Constructor<?> reflectTestClassObj = ReflectTestClass.class.getDeclaredConstructor();reflectTestClassObj.setAccessible(true);reflectTestClassObj.newInstance();} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {e.printStackTrace();}try {// 1.3获取带参数的构造方法构建的对象// 注意区分 ReflectTestClass.class.getConstructor() 这个方法返回的是public的构造方法Constructor<?> reflectTestClassObj = ReflectTestClass.class.getDeclaredConstructor(String.class);reflectTestClassObj.setAccessible(true);reflectTestClassObj.newInstance("AAAA");} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {e.printStackTrace();}}// 2 反射调用filedprivate void getPrivateField() {ReflectTestClass object = null;try {Constructor<?> reflectTestClassObj = ReflectTestClass.class.getDeclaredConstructor(String.class);reflectTestClassObj.setAccessible(true);object = (ReflectTestClass) reflectTestClassObj.newInstance("AAAA");} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {e.printStackTrace();}if (object == null){return;}// 开始访问私有变量try {Field field = ReflectTestClass.class.getDeclaredField("mName");field.setAccessible(true);String name = (String) field.get(object);Log.e(TAG, "getPrivateField: mName "+name);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}// 3 反射调用methodprivate void getPrivateMethod() {ReflectTestClass object = null;try {Constructor<?> reflectTestClassObj = ReflectTestClass.class.getDeclaredConstructor(String.class);reflectTestClassObj.setAccessible(true);object = (ReflectTestClass) reflectTestClassObj.newInstance("AAAA");} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {e.printStackTrace();}if (object == null){return;}// 开始访问私有method// 3.1 调用无参方法try {Method method = ReflectTestClass.class.getDeclaredMethod("getName");method.setAccessible(true);method.invoke(object);} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {e.printStackTrace();}// 3.2 调用含有参数的方法try {Method method = ReflectTestClass.class.getDeclaredMethod("setName",String.class);method.setAccessible(true);method.invoke(object,"CCCC");} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {e.printStackTrace();}}// 4 反射调用hide的方法或类// AssetManager addAssetPath(String path)是一个hide的方法 调用方式其实和普通方法反射调用一样private void getHideMethod() {AssetManager assetManager = null;try {assetManager = AssetManager.class.newInstance();Method addAssetPathMethod = AssetManager.class.getDeclaredMethod("addAssetPath",String.class);// addAssetPath(String path)addAssetPathMethod.invoke(assetManager,"sdcard/app/red.skin");} catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException e) {e.printStackTrace();}}
}
最后的输出:
2021-07-14 21:43:23.363 18882-18882/com.example.d04reflectgeneric E/MyActivity: testReflect: start ======>
2021-07-14 21:43:23.364 18882-18882/com.example.d04reflectgeneric W/System.err: java.lang.IllegalAccessException: void com.example.d04reflectgeneric.reflect.ReflectTestClass.<init>() is not accessible from java.lang.Class<com.example.d04reflectgeneric.MainActivity>
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/ReflectTestClass: Constructor without parameters is called
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/ReflectTestClass: Constructor with parameter String called
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/MyActivity: testReflect: end ======>
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/ReflectTestClass: Constructor with parameter String called
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/MyActivity: getPrivateField: mName AAAA
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/MyActivity: getPrivateMethod: start ======>
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/ReflectTestClass: Constructor with parameter String called
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/ReflectTestClass: getName: AAAA
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/ReflectTestClass: setName: CCCC
2021-07-14 21:43:23.365 18882-18882/com.example.d04reflectgeneric E/MyActivity: getPrivateMethod: end ======>
2. 注解
Xutil的View查找就是利用了反射+注解实现的
我在手写注解框架中简单介绍了注解
https://blog.csdn.net/u011109881/article/details/113854660
即像Xutil一样通过反射和注解去 findViewById
注解比较简单,它只是一个标记,没有具体的功能逻辑代码。
3. 泛型
类泛型 在任何地方出现的,代表的是统一类型
/*** Created by hjcai on 2021/7/15.* 类泛型学习*/
public class Container<T> {//此处的<T>是泛型的声明// 创建只能存储固定类型的数组private Object[] items = new Object[10];public void add(T t) {items[0] = t;}public T get(int index) {return (T) items[index];}
}
方法泛型
/*** Created by hjcai on 2021/7/15.* <p>* 方法泛型学习*/
public class MethodGeneric/*如果把<T>泛型申明移到这里就是类的泛型了 T可以在类内部使用 方法上的<T>的声明就可以删除了*/ {// <T>表示在方法中声明泛型public <T> void onSuccess(T result) {}
}
泛型的上限与下限
/*** Created by hjcai on 2021/7/15.* 泛型上限 泛型下限 学习*/
public class BaseActivity extends AppCompatActivity {// 泛型上限 传入的参数必须是BaseActivity及其子类// 上限是BaseActivity// ? 代表任意的意思public void startActivity(Class<? extends BaseActivity> clazz) {Intent intent = new Intent(this, clazz);startActivity(intent);}// 泛型下限 传入的参数必须是BaseActivity及其父类// 下限是BaseActivitypublic void startActivity1(Class<? super BaseActivity> clazz) {Intent intent = new Intent(this, clazz);startActivity(intent);}
}
泛型远不止上面说的这么简单 上述的只是泛型的基本知识 泛型更复杂的还有泛型在元组上的运用 泛型类型的擦除 泛型的缺陷等等 目前其实还有很多地方不太了解 贴一下以前看think in java的笔记
https://blog.csdn.net/u011109881/article/details/102658032
真的是学的越多,感觉自己不知道的就越多。。。
红橙Darren视频笔记 反射注解泛型简介相关推荐
- 红橙Darren视频笔记 IOC注解框架 了解xUtils3与ButterKnife的原理
1.什么是IOC IOC是Inversion of Control的缩写,直接翻译过来就叫依赖反转,看起来感觉不明觉厉,我觉得IOC就是一种解耦方式.比如原本我们在Activity中findviewb ...
- 红橙Darren视频笔记 IOC注解框架 自己写个注解框架
本节是架构篇开篇 这里先解释一下最终项目的架构 目标 目标就是不需要进行一大堆的findviewbyid以及各种setListener的杂乱代码,本文以findviewbyid和setOnClickL ...
- 红橙Darren视频笔记 UML图简介
整体架构复制自红橙原视频的课堂笔记 因为他这一课没有博客,所以没有转载链接,CSDN没有转载地址是无法作为转载类型的文章发表的,暂时标记为原创 参考链接 https://blog.csdn.net/r ...
- 红橙Darren视频笔记 代理模式 动态代理和静态代理
红橙Darren视频笔记 代理模式 动态代理和静态代理(Android API 25) 关于代理模式我之前有过相关的介绍: https://blog.csdn.net/u011109881/artic ...
- 红橙Darren视频笔记 类加载机制(API28) 自己写个热修复 查看源码网站
第一部分 类加载机制 一个Activity是如何被Android虚拟机找到的? 在之前的文章 红橙Darren视频笔记 自定义View总集篇(https://blog.csdn.net/u011109 ...
- 红橙Darren视频笔记 利用阿里巴巴AndFix进行热修复
注意 由于AndFix在2017年左右就停止更新了,在最新版本的apk上遇到很多问题,我最终也没有成功进行热修复.本节主要是学习热修复的原理 在上一篇 红橙Darren视频笔记 自己捕获异常并保存到本 ...
- 红橙Darren视频笔记 Behavior的工作原理源码分析
主要coordinatorlayout的代码来自coordinatorlayout-1.0.0-sources.jar 本文从源码介绍 CoordinatorLayout 的 behavior 怎么工 ...
- 红橙Darren视频笔记 仿QQ侧滑效果
这一篇没有什么新的内容 就是改写 红橙Darren视频笔记 仿酷狗侧滑效果 的侧滑的效果 1.去掉淡入淡出效果 2.加上黑色模板效果 效果: 去掉淡入淡出效果很简单 就是注释掉onScrollChan ...
- 红橙Darren视频笔记 ViewGroup事件分发分析 基于API27
本节目标,通过案例,先看程序运行结果,然后跟踪源码,理解为什么会有这样的输出,继而理解view group的分发机制,感觉和证明题很像呢. 考虑以下程序的运行结果: case1: public cla ...
最新文章
- sklearn 相似度矩阵_精简易懂,30 分钟学会 SVD 矩阵分解,很强!
- 求1!+2!+3!+...+10!的值
- 大数据和hadoop的一些基础知识
- 3. 视图数据View Data和Balde模版 - Laravel从零开始教程
- 服务器 不支持gbk,解决JS请求服务器gbk文件乱码的问题
- 有关分库分表你想知道的,都在这儿了
- HighCharts:plotLines基准线与数据相差过大不显示
- (原创)Windows系统后安装ubuntu,无法选择启动ubuntu。
- java把行政区划放到一个节点树形中
- 一文详解谷歌最新物联网操作系统 Android Things,话说还记得大明湖畔的Fuchsia吗?
- 不同计算机通过家庭组无法共享的是,windows7开家庭组与其他版本系统共享文件失败的解决方法...
- 江西理工大学计算机网络基础试卷,无线网络技术作业(江西理工大学期末复习)...
- DHCP地址池耗尽攻击
- Android实现身份证识别
- 帝国CMS采集插件哪个好用?帝国CMS采集文章教程
- linux系统安装teamview,在Ubuntu 18.04系统上安装TeamViewer的两种方法
- MUI增加BeeCloud支付集成示例
- 贝壳二手房爬虫,搞搞房价
- HTML -JavaScript--模拟病毒
- AirPods过河,苹果拆桥:被“钞能力”征服的Beats何以至此?