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视频笔记 反射注解泛型简介相关推荐

  1. 红橙Darren视频笔记 IOC注解框架 了解xUtils3与ButterKnife的原理

    1.什么是IOC IOC是Inversion of Control的缩写,直接翻译过来就叫依赖反转,看起来感觉不明觉厉,我觉得IOC就是一种解耦方式.比如原本我们在Activity中findviewb ...

  2. 红橙Darren视频笔记 IOC注解框架 自己写个注解框架

    本节是架构篇开篇 这里先解释一下最终项目的架构 目标 目标就是不需要进行一大堆的findviewbyid以及各种setListener的杂乱代码,本文以findviewbyid和setOnClickL ...

  3. 红橙Darren视频笔记 UML图简介

    整体架构复制自红橙原视频的课堂笔记 因为他这一课没有博客,所以没有转载链接,CSDN没有转载地址是无法作为转载类型的文章发表的,暂时标记为原创 参考链接 https://blog.csdn.net/r ...

  4. 红橙Darren视频笔记 代理模式 动态代理和静态代理

    红橙Darren视频笔记 代理模式 动态代理和静态代理(Android API 25) 关于代理模式我之前有过相关的介绍: https://blog.csdn.net/u011109881/artic ...

  5. 红橙Darren视频笔记 类加载机制(API28) 自己写个热修复 查看源码网站

    第一部分 类加载机制 一个Activity是如何被Android虚拟机找到的? 在之前的文章 红橙Darren视频笔记 自定义View总集篇(https://blog.csdn.net/u011109 ...

  6. 红橙Darren视频笔记 利用阿里巴巴AndFix进行热修复

    注意 由于AndFix在2017年左右就停止更新了,在最新版本的apk上遇到很多问题,我最终也没有成功进行热修复.本节主要是学习热修复的原理 在上一篇 红橙Darren视频笔记 自己捕获异常并保存到本 ...

  7. 红橙Darren视频笔记 Behavior的工作原理源码分析

    主要coordinatorlayout的代码来自coordinatorlayout-1.0.0-sources.jar 本文从源码介绍 CoordinatorLayout 的 behavior 怎么工 ...

  8. 红橙Darren视频笔记 仿QQ侧滑效果

    这一篇没有什么新的内容 就是改写 红橙Darren视频笔记 仿酷狗侧滑效果 的侧滑的效果 1.去掉淡入淡出效果 2.加上黑色模板效果 效果: 去掉淡入淡出效果很简单 就是注释掉onScrollChan ...

  9. 红橙Darren视频笔记 ViewGroup事件分发分析 基于API27

    本节目标,通过案例,先看程序运行结果,然后跟踪源码,理解为什么会有这样的输出,继而理解view group的分发机制,感觉和证明题很像呢. 考虑以下程序的运行结果: case1: public cla ...

最新文章

  1. sklearn 相似度矩阵_精简易懂,30 分钟学会 SVD 矩阵分解,很强!
  2. 求1!+2!+3!+...+10!的值
  3. 大数据和hadoop的一些基础知识
  4. 3. 视图数据View Data和Balde模版 - Laravel从零开始教程
  5. 服务器 不支持gbk,解决JS请求服务器gbk文件乱码的问题
  6. 有关分库分表你想知道的,都在这儿了
  7. HighCharts:plotLines基准线与数据相差过大不显示
  8. (原创)Windows系统后安装ubuntu,无法选择启动ubuntu。
  9. java把行政区划放到一个节点树形中
  10. 一文详解谷歌最新物联网操作系统 Android Things,话说还记得大明湖畔的Fuchsia吗?
  11. 不同计算机通过家庭组无法共享的是,windows7开家庭组与其他版本系统共享文件失败的解决方法...
  12. 江西理工大学计算机网络基础试卷,无线网络技术作业(江西理工大学期末复习)...
  13. DHCP地址池耗尽攻击
  14. Android实现身份证识别
  15. 帝国CMS采集插件哪个好用?帝国CMS采集文章教程
  16. linux系统安装teamview,在Ubuntu 18.04系统上安装TeamViewer的两种方法
  17. MUI增加BeeCloud支付集成示例
  18. 贝壳二手房爬虫,搞搞房价
  19. HTML -JavaScript--模拟病毒
  20. AirPods过河,苹果拆桥:被“钞能力”征服的Beats何以至此?

热门文章

  1. 软件工程(2019)第二次作业
  2. 阿里Java研发工程师实习面经
  3. 浅谈js中的this
  4. 对上一篇博客问题的回应
  5. Linux下ftp的安装配置
  6. 常见设计模式结构图助记之结构型
  7. 在索引列上正确使用LIKE运算符
  8. VS2008(C#)子页嵌套母版页的控件访问方法(二)
  9. delphi 调用 c# 写的webservice
  10. hadoop文件操作