Java基础之反射、注解、代理
反射
笔者对反射的理解就是解剖class文件,来进行一系列操作。
Class类
获取Class类实例的三种方式:
- 类名.class
- 对象.getClass()
static Class forName(String className)根据类的名称获取类的Class对象(这里的className必须是类的全名)
一般使用第三种方式获取Class对象。
常用成员方法:
Field getField(String name)获取类中的成员变量的对象String getName()获取类的全名:包名.类名String getSimpleName()获取类的简称:类名String getPackageName()获取包名Field getField(String name)获取公共成员变量对象Method getMethod(String name, Class<?>... parameterTypes)获取类中的公共成员函数的对象Constructor<T> getConstructor(Class<?>... parameterTypes)获取类中的公共构造函数的对象newInstance()获取该类的实例(JDK 9已过期,使用clazz.getDeclaredConstructor().newInstance() 实例化)
静态:
forName(String className)加载类
其中成员变量、成员函数、构造函数要素过多,使用了独立的类来描述:
| 类 | 描述 |
|---|---|
| Field | 成员变量 |
| Method | 成员方法 |
| Constructor | 构造方法 |
预定义对象:八中基本类型以及void,其class对象就是其本身
Constructor、Method、Field
Constructor
newInstance(Object... initargs)获取实例setAccessible(boolean)是否可以暴力访问,即越过私有权限的检验
setAccessible(boolean)是其父类的方法,Field、Method、Constructor都可以设置暴力访问私有方法/变量。
Method
Object invoke(Object obj, Object... args)调用方法,返回值为该方法的返回值(void方法返回null),第一个参数为调用的对象,第二个参数为方法的参数
类加载器
常见的类加载器有三种,每个类加载器负责加载不同位置的类:
| 加载器 | 说明 |
|---|---|
| Bootstrap 根类加载器 | Bootstrap是最顶级的类加载器。它加载类文件不是我们自己书写的,负责Java核心类的,比如System,String等。只有所有类加载到内存中,我们才可以使用。(Bootstrap自动加载) |
| ExtClassLoader 扩展类加载器 | ExtClassLoader 扩展类加载器,加载的是扩展类的,我们是用不到的,都是jdk内部自己使用的。(ExtClassLoader类被BootStrap加载) |
| AppClassLoader 系统/应用类加载器 | AppClassLoader 系统/应用类加载器,是用来加载ClassPath 指定的所有jar或目录,ClassPath表示存放类路径的,我们如果不配置ClassPath,那么就表示当前文件夹,在idea环境下的ClassPath是out目录。在out目录存放的都是我们书写好的class文件,也就是说 AppClassLoader 类加载器是用来加载我们书写的out目录下的class文件。(AppClassLoader类被ExtClassLoader加载) |
默认相对目录(文件路径)为相对项目目录,加载器相对目录为src
注解
JDK 常用注解:
| 注解 | 用途 |
|---|---|
@Override |
重写 |
@SuppressWarnings() |
抑制警告 |
@FunctionalInterface |
函数式接口 |
@SuppressWarnings()参数关键字列表:
| 参数 | 描述 |
|---|---|
| all | to suppress all warnings (抑制所有警告) |
| boxing | to suppress warnings relative to boxing/unboxing operations(抑制装箱、拆箱操作时候的警告) |
| cast | to suppress warnings relative to cast operations (抑制映射相关的警告) |
| dep-ann | to suppress warnings relative to deprecated annotation(抑制启用注释的警告) |
| deprecation | to suppress warnings relative to deprecation(抑制过期方法警告) |
| fallthrough | to suppress warnings relative to missing breaks in switch statements(抑制确在switch中缺失breaks的警告) |
| finally | to suppress warnings relative to finally block that don’t return (抑制finally模块没有返回的警告) |
| hiding | to suppress warnings relative to locals that hide variable() |
| incomplete-switch | to suppress warnings relative to missing entries in a switch statement (enum case)(忽略没有完整的switch语句) |
| nls | to suppress warnings relative to non-nls string literals(忽略非nls格式的字符) |
| null | to suppress warnings relative to null analysis(忽略对null的操作) |
| rawtypes | to suppress warnings relative to un-specific types when using generics on class params(使用generics时忽略没有指定相应的类型) |
| restriction | to suppress warnings relative to usage of discouraged or forbidden references |
| serial | to suppress warnings relative to missing serialVersionUID field for a serializable class(忽略在serializable类中没有声明serialVersionUID变量) |
| static-access | to suppress warnings relative to incorrect static access(抑制不正确的静态访问方式警告) |
| synthetic-access | to suppress warnings relative to unoptimized access from inner classes(抑制子类没有按最优方法访问内部类的警告) |
| unchecked | to suppress warnings relative to unchecked operations(抑制没有进行类型检查操作的警告) |
| unqualified-field-access | to suppress warnings relative to field access unqualified (抑制没有权限访问的域的警告) |
| unused | to suppress warnings relative to unused code (抑制没被使用过的代码的警告) |
自定义注解
声明注解
自定义注解使用@interface声明
其内可以有属性:public abstract 属性类型 属性名() default 属性的默认值;
注解中public abstract可以省略,并且属性类型只能是是:基本类型、String、Class、注解,以及以上类型的一维数组,属性可以没有默认值。
使用注解
注解可以没有属性,如果有属性需要在括号内赋值,有默认值可以不赋值。
相同注解在同一方法只能使用一次。
解析自定义注解
元注解
元注解是用来标记注解的注解。
一共有四种:
@Target用于确定被修饰的注解使用的位置(主要)@Retention用于确定被修饰的自定义注解生命周期(主要)@Documented将此注解包含在Javadoc中@Inherited允许子类继承父类中的注解
@Target:表示该注解可以用于什么地方。可能的ElementType参数包括:CONSTRUCTOR:构造器的生命FIELD:域声明(包括enum实例)LOCAL_VARIABLE:局部变量声明METHOD:方法声明PACKAGE:包声明PARAMETER:参数声明TYPE:类、接口(包括注解类型)和enum声明ANNOTATION_TYPE:注解声明(与TYPE的区别?专门用在注解上的TYPE)TYPE_PARAMETER:Java8TYPE_USE:Java8
@Retention:
表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:SOURCE:注解将在编译器丢弃CLASS:注解在class文件中可用,但会被VM丢弃RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
可以通过反射拿到方法,然后拿到注解,通过拿到的注解便可以拿到注解中的值。
代理
静态代理
代理:代理对象主要用来拦截目标业务对象的访问
- 代理对象要持有真实业务对象。(在代理类中创建被代理类的对象。)
- 代理对象要和真实业务对象,具备相同的行为方法。实现同一个接口。
- 代理对象拦截对真实对象的访问,可以修改访问的参数、返回值,甚至拦截访问。
静态代理使用较少。
动态代理
动态代理:就是在程序运行的过程中,动态的生成一个类,这个类要代理目标业务对象,并且可以动态生成这个代理类的对象。
在Java中当某个类需要被代理的时候,要求这个类中的被代理的方法必须抽取到一个接口中,然后这个类需要实现那个接口,只有在这个接口中的方法,代理类才能代理它。
Proxy类
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h):
获得代理类实例,参数:
ClassLoader loader类加载器,一般给被代理对象的类加载器即可
Class<?>[] interfaces被代理对象的所有的接口数组
InvocationHandler h调用处理器,是一个接口。
InvocationHandler接口有一个静态方法:public Object invoke(Object proxy, Method method, Object[] args)
第一个参数是代理本身,第二个参数是调用的方法,第三个参数是调用方法的参数(在方法中this是这个接口的实现类,proxy才是代理本身,通过返回代理本身可以实现链式调用,参考这里)
上个栗子:
@Test
public void proxyTest() throws Exception {
//获取自定义类的Class对象
Class clazz = Class.forName("org.junit.sh.n1.Person");
//获取该类的类加载器
ClassLoader loader = clazz.getClassLoader();
//获取接口数组
Class[] interfaces = clazz.getInterfaces();
// @SuppressWarnings("all")//clazz.newInstance()方法在JDK9中过期了,懒得改了,注解一下
//实例化一个对象作为调用者
Person p = (Person) clazz.newInstance();
//使用Lambda实现InvocationHandler
InvocationHandler h = (proxy, method, args) -> {
if ("show".equals(method.getName())) {
System.out.println("修改方法");
return method.invoke(p, args);
}
return null;
};
//自定义类实现的接口
Showable theProxy = (Showable) Proxy.newProxyInstance(loader, interfaces, h);
//调用方法
theProxy.show();
}
真正理解反射和注解还是得结合框架(。・∀・)ノ
Java基础之反射、注解、代理的更多相关文章
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 | 被围观 25,969 views+ 1.Anno ...
- 黑马程序员:Java基础总结----反射
黑马程序员:Java基础总结 反射 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- 【Java基础】反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- 学习Spring必学的Java基础知识(2)----动态代理
Spring AOP使用动态代理技术在运行期织入增强的代码,为了揭示Spring AOP底层的工作机理,有必要对涉及到的Java知识进行学习.Spring AOP使用了两种代理机制:一种是基于JDK的 ...
- Java基础之一反射
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...
- Java基础之—反射
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...
- java基础篇---反射机制
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
- Java基础教程(16)--注解
一.注解基础知识 1.注解的格式 最简单的注解就像下面这样: @Entity @符号指示编译器其后面的内容是注解.在下面的例子中,注解的名称为Override: @Override void ...
- JAVA基础知识|反射
一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为ja ...
随机推荐
- MIT课程
8.02 Physics II (电磁学基础) Introduction to electromagnetism and electrostatics: electric charge, Coulo ...
- iplimage 转HBITMAP
HBITMAP IplImage2hBitmap(IplImage* pImg) { cvFlip(pImg, NULL); BYTE tmp[]; BITMAPINFO *bmi = (BITMAP ...
- Python+opencv+pyaudio实现带声音屏幕录制
原文链接:https://blog.csdn.net/zhaoyun_zzz/article/details/84341801 Python+opencv+pyaudio实现带声音屏幕录制原创luke ...
- dmp文件自动分析
dmp文件的分析,可以借助各种工具,比如WinDbg, CDB , NTSD,KD等.Windbg提供了窗口接口,而CDB , NTSD是基于命令行的工具,它们都使用了同样的调试引擎Dbgeng.dl ...
- 019、MySQL取本季度开始时间和本季度结束时间
SELECT QUARTER ( adddate( dy, ) ) QTR, date_add( dy, INTERVAL MONTH ) Q_start, adddate( dy, ) Q_end ...
- Django(十三)状态保持 —— cookie与session+ajax异步请求+session记住登录状态+cookie记住登录名密码
一.状态保持的概述 http协议是无状态的.下一次去访问一个页面时并不知道上一次对这个页面做了什么.因此引入了cookie.session两种方式来配合解决此问题. Duplicate entry:重 ...
- 用QEMU模拟运行uboot从SD卡启动Linux
平台:Qemu + vexpress-a9 u-boot:u-boot-2019.10 Linux:linux-4.14.13 之前介绍过用Qemu模拟运行uboot,然后从网络启动lin ...
- c++输出哈夫曼编码
#include<iostream> #include<string> using namespace std; struct huffTree { int parent; i ...
- Oracle-SQL 小题
1.查询姓名中不包含C和c的员工信息 ; ①字符函数 instr(input,char,m,n) 的用法:返回在字符值中查找字符串char的数字位置.参数m作为查找的开始,参数n代表第n次发现.m和n ...
- 【CS224n-2019学习笔记】Lecture 1: Introduction and Word Vectors
附上斯坦福cs224n-2019链接:https://web.stanford.edu/class/archive/cs/cs224n/cs224n.1194/ 文章目录 1.课程简单介绍 1.1 本 ...