学习资源整理自:B站《狂神说》
注解 Annotation
从JDK5.0开始使用
-
注解的作用
- 不是程序本身,可以对程序作出解释(类似于注释,用于说明)
- 可以被其他程序读取(编译器等)
-
注解的格式
- 注解以 @注解名 存在,可以带有参数
-
一般应用场景
- 可以附加在package、class、method、field等上,给这些元素添加额外的辅助信息,并且可以通过反射机制对这些信息进行获取
元注解
-
元注解的作用是注解其它注解,java定义了4个标准的meta-annotation类型,他们被用来提供对其它annotation类型做说明;
-
这些类型和它们所支持的类在java.lang.annotation包中可以找到
- @Target:用于描述注解的适用范围(描述注解可以用在什么地方)
- @Retention:表示需要在什么级别保存改注解信息,描述注解的生命周期
- (SOURCE < CLASS < RUNTIME )
- @Document:说明该注解将被包含在javadoc中
- @Inherited:说明子类可以继承父类中的该注解,注解的继承
自定义注解
- 使用@interface声明注解,public @interface name{}
- 自动继承java.lang.annotation.Annotation接口
- 其中每个方法实际声明一个配置参数,方法名就是参数名,返回值类型就是参数类型(返回值只能是基本类型,Class、String、enum)
- 可以通过default来声明参数的默认值
- 如果只有一个参数成员,一般命名为value
- 注解元素必须要有值,我们定义注解元素时,经常使用空字符串 0 作为默认值。
反射 Reflection
反射概述
- 反射是java被视为动态语言的关键,反射机制允许程序在执行期接住Reflection Api获取类的任何内部信息,并能直接操作任何对象的内部属性及方法。
- 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象,这个对象包含了完整的类的结构信息,于是通过这个对象可以看到类的结构。这个对象就像一面镜子,所以称之为反射。
可以读取到private修饰的类和方法。
java反射机制提供的功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时获取泛型信息
- 在运行时调用任意一个对象的成员变量和方法
- 在运行时处理注解
- 生成动态代理
- …
Java反射的优点:
- 可以实现动态编译和创建对象,体现了很大的灵活性;
Java反射的缺点:
- 对性能有影响。使用反射基本上是一种解释操作,这类操作总是慢于直接执行相同的操作。
Class类并获取Class实例
- Class本身也是一个类
- Class对象只能由系统创建
- 一个加载的类在JVM中只会有一个Class实例
- 一个Class对象对应的是一个加载到JVM中的一个.class文件
- 通过Class可以完整的得到一个类中的所有被加载的结构
- Class类是Reflection的根源,针对任何你想动态加载、运行的类都需要先获得相应的Class对象。
Class类常用方法
方法名 | 说明 |
---|---|
static Class.forName(String name) | 获得指定类名的Class对象 |
Object newInstance() | 调用无参构造器,创建Class对象的一个实例 |
getName() | 返回此Class对象所表示的实体(类、接口、数组类或void)的名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class[] getInterfaces() | 获取当前Class对象的接口的Class数组 |
ClassLoader getClassLoader() | 返回此类的类加载器 |
Constructor[] getConstructors() | 获取当前Class对象的构造器数组 |
Method getMothed(String name,Class …T) | 返回一个Method对象,此对象的形参类型为paramType |
Field[] getDeclaredFields() | 获取当前Class对象的字段数组 |
获取Class类的方法:
- 根据类名直接获取
Class clazz = Person.class;
- 由实例获取:
Class calzz = sutdent.getClass();
- 根据类的路径获取:
Class clazz = Class.forName("com.ssx.People");
- 内置基本数据类型可以直接使用 .Type
- 可以通过ClassLoader获取
全类型Class
类的加载与ClassLoader
当程序主动使用一个未被加载到内存中的类时,系统会通过以下三步对该类进行初始化
参考JVM回首会更清晰。
引导类加载器:rt.jar
类加载演示
反射获取泛型
- Java采用泛型擦除的机制来引入泛型,Java中的泛型仅仅是给编译器javac使用的,确保数据的安全性和免去强制类型转换问题,可是一旦编译完成所有和反省有关的类型全部擦除
- 为了通过反射操作这些类型,Java增加了ParameterizedType、GenericArrayType、TypeVariable和WildcardType几种类型来代表不能被归类到Class类中的类型但是又和原始类型齐名的类型
- ParameterizedType:一种参数化类型,比如:Collection
- GenericArrayType:一种元素类型是参数化类型或者类型变量的数组类型
- TypeVariable:是各种类型变量的公共父接口
- WildcardType:代表一种通配符类型表达式
反射获取注解
Annotation annotation = clazz.getAnnotations();//获取全部注解
clazz.getAnnotation(anno.class);
annotation.value()