杂杂碎知识
最近在阅读 spring 源码,学到很多原来没用过的 java api,如果未来自己要实现某些框架,将非常有用。
注解方面
所有的注解都继承自 Annotation 接口
@Inherited
一般而言子类上是看不到父类上的注解的,除非这个注解上加了 @Inherited 注解
@Retention(RetentionPolicy.RUNTIME)
用来修饰注解保留的时间,有三个值,默认值为 CLASS
- SOURCE 只保留在源代码阶段,不会被编译,用于一些做检查的操作,如@SuppressWarnings、@Override
- CLASS 只保留在class文件中,可以通过编译,但不会被jvm执行
- RUNTIME 可以被jvm执行,比如需要运行时获取注解信息,如反射
AnnotatedElement 接口
表示当前在此虚拟机中运行的程序的带批注元素。此接口允许反射地读取批注。全部
此接口中的方法返回的批注是不可变和可序列化的。此接口的方法返回的数组可以由调用方修改,而不影响返回给其他调用方的数组。
这个接口中有一些方法很实用,如果获取不到某些注解,确保注解上有@Retention(RetentionPolicy.RUNTIME)
- getAnnotations() 获取此类上的所有注解
- getDeclaredAnnotations() 获取此类上的所有注解(不包括此类父类上的注解)
- isAnnotationPresent() 判断此类上是否有某个注解(包括父类上的注解)
这个接口有很多实现,例如 Package、Class、Method、Field
Class 方面
在Class.java中的注释提到,类分为五种:
1 | // There are five kinds of classes (or interfaces): |
- a:顶级类
- b:静态内部类
- c:非静态内部类
- d:在方法内定义的类
- e:匿名类
spring中 ClassMetadata
接口中的 boolean isIndependent();
方法,根据其注释描述,功能为 确定类是否独立,即是否是顶级类(top level)或嵌套类(静态内部类)可以独立于封闭类构造。
查看SimpleAnnotationMetadata
的实现
1 | public boolean isIndependent() { |
先判断enclosingClassName
是否为null,即是否是top level 类,如果不是,再判断independentInnerClass
,即是否是静态内部类。
如何获取 enclosingClassName 变量的呢? Class中有方法 Class<?> getEnclosingClass()
,如果一个类不是top level的话,就会返回包含这个类的 top level,如果类是top level,那么返回 null 。
如何获取 independentInnerClass 变量的呢?spring使用了ASM技术:
ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
简单说ASM能够解析class文件内容,且提供接口能CRUD,而反射只能读取内容。
再看一下independentInnerClass
变量是什么时候被赋值的:
1 | public void visitInnerClass(String name, String outerName, String innerName, |
spring
设计模式
可以使用枚举来实现工厂模式,更加优雅
1 | public interface FoodFactory { |