注解

元注解

@Inherited 注解可以被子类继承

@Documented 文档注释会包含在javadoc

@Retention 注释在什么时候生效 Runtime Class Sources

@Target 注释可以使用在什么地方

自定义注解

@Target({ElementType.TYPE,ElementType.METHOD})
@Rentention(RelenLionPolicy.RUNTIME)
@Interface MyAnnotation{
    String value() defalut "";
    int id() default -1;
    String[] schools() default {"",""};
}

类加载和初始化分析

类的加载

一、加载

  • JVM通过类的全限定名获取该类的二进制(Class)文件
  • 将该二进制文件转化为运行时数据结构
  • 在方法区中生成java.lang.Class对象,作为该数据结构的访问接口

二、连接

  • 验证:验证该类是否有合理的数据结构,类数据是否符合JVM的要求
  • 准备:在方法区中为静态变量(static)分配内存,并赋予默认值,如static int a = 100,a在准备阶段就被赋予了默认值0,静态常量(final static)在准备阶段就被赋予了值,例如final static a = 100,a变量在准备阶段就被赋值为100,而静态变量要等到类初始化才会被赋值
  • 解析:将二进制数据中的符号引用替换为直接引用

三、初始化

执行所有被static修饰的代码,包括变量和代码块,如果是静态变量则设置初始值,如果是静态方法则按顺序执行静态方法的代码。

类的加载器

类通过加载器进行加载主要包括

根类加载器(BootStrap ClassLoader) 加载核心类库(rt.jar),用户无法获取

扩展类加载器(Extension ClassLoader) 加载扩展类jar包

系统类加载器(Application ClassLoader) 加载指令目录下的jar包

加载器的层级为:根类加载器>扩展类加载器>系统类加载器

当加载一个类的时候,较低层会逐级询问高层是否已加载该类

类的初始化

主动引用的时候会触发类的初始化

主动引用包括

  • 系统执行main方法的时候
  • new一个实例的时候
  • 调用类的静态方法和静态变量(除final)的时候
  • 使用反射创建对象的时候
  • 一个类父类未被初始化,先初始化父类

类的被动引用

  • 访问一个静态域,只有真正生命这个域的类才会被初始化,例如子类调用父类的静态方法不会被初始化
  • 创建数组的时候不会初始化类
  • 使用常量的时候不会被初始化

反射获得类

Class clazz = Class.forName("com.jun.Persion");

Class clazz = Persion.class;

Class clazz = student.getClass();

Class clazz = Integer.TYPE;
Perison.class;//类

Comparable.class;//接口

Overide.class;//注解


//数组维度和类型相同,则为同一个class
int[].class;//一维数组

int[][].class;//二维数组

ElementType.class;//枚举

Integer.class;//基本类型

void.class;//void

Class.class;//Class

反射常用方法

Class clazz = Class.forName("com.jun.User");
//获得构造器
Constructor constructor = clazz.getDeclaredConstructor(int.calss,String.class);
User user = (User)constructor.newInstance(20,"Bob");
//获得方法
Method method = clazz.getDeclaredMethod("setName",String.class);
method.invoke(user,"Tom");
//获得字段
Filed name = clazz.getDeclaredFiled("name");
name.setAccessible(false);
name.set(user,"Test");
//获得注解
clazz.getAnnotation(TableName.class);
clazz.getDeclaredField("name").getgetAnnotation(Detail.class);