注解和反射
一 、什么是注解
@Overide @Deprecated @SuppressWarning …
带有@符号的都是注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();// 这个东西是参数 说明@Target这个注解的参数是个数组
}
二、有什么作用
-
注释、解释
-
能够被程序读取到
三、4个元注解
定义注解的默认注解
@Target({ElementType.TYPE, ElementType.FIELD}) 定义在哪里可以加这个注解
@Retention(RetentionPolicy.RUNTIME) 定义注解的生存时间 RUNTIME>CLASS>SOURCE
@Documented 是否生成文档
@Inherited 是否能被子类继承
四、什么是反射
通过Class来获取要操作的对象或者Method等
如何获取Class
// 方法1
Class c1 = Class.forName("com.test.User");
// 方法2
Class c2 = User.class;
// 方法3
User user = new User();
Class c3 = user.getClass();
Class在JVM中只加载一次
所以上面即使3种方法获取User的Class,它们获取的都是同一个Class
// hashcode相同
System.out.print(c1.hashCode());
System.out.print(c2.hashCode());
System.out.print(c2.hashCode());
五、Class Field Method Constractor API使用
API大致都类似
带有Declared的可以获取私有方法
不带的只能获取公共方法
可以获取类中全部的会返回数组
也可获取单独某一个 需要传参字符串名称
六、类加载机制
-
加载
类加载器将class字节码文件加载到JVM
详细说来,是把class文件中的二进制数据加载到方法区中,并在堆中创建对应的Class对象。Class对象(类的数据结构的封装)
-
连接
1) 校验 校验加载的类是否符合虚拟机规范 重要非必须 可以通过-Xverfity:none关闭
2) 准备 静态变量赋初始化值
3) 解析 虚拟机将常量池中的符号引用转化为直接引用
-
初始化
调用clInit方法初始化
1) 如果父类没有初始化 先加载初始化父类
2) 进行初始化
-
使用
-
卸载
七、类加载器 双亲委派机制
名称 | 类加载器 | 描述 |
---|---|---|
引导类加载器 | Bootstrap ClassLoader | C++编写 Java无法直接获取 加载jvm核心类 lib包下rt.jar等 |
扩展类加载器 | Extension ClassLoader | 加载lib/ext下的扩展类 |
系统类加载器 | Application ClassLoader | 加载当前应用classpath下的类 |
自定义类加载器 | User ClassLoader |
类加载器的层次关系
双亲委派机制
当低层级的类加载器加载类时,它会先委托上一级的类加载器加载,如果上级的类加载器加载了,低级类就不加载了直接使用。否则低层级的再去加载类。
好处:
- 避免重复加载
- 保证安全性
八、反射获取注解
自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnotation {
String[] value();
String name();
}
将自定义注解加到方法上
public class Word {
private String name;
private String explain;
private String instance;
@MyAnotation(value = {"sss", "555"}, name = "abc")
public void testAnnotation(){
}
}
获取注解
public static void main(String[] args) throws Exception {
Class c2 = Class.forName("com.zyw.esdic.pojo.Word");
Method test1 = c2.getMethod("testAnnotation");
MyAnotation annotation = test1.getAnnotation(MyAnotation.class);
System.out.println(Arrays.toString(annotation.value()));
System.out.println(annotation.name());
}
输出结果:
[sss, 555]
abc