一、内置注解
- @Override:只用于修饰方法,表示方法重写
- @Deprecated:由于修饰方法、属性、类,表示不推荐使用
- @SupperessWarings:抑制警告
二、元注解
- @Target:用于描述注解的使用范围
- @Retention:用于描述注解的生命周期
- @Documented:是否生成文档注释
- @Inherited:子类可以继承父类的注解
三、自定义注解
package annotation;
import java.lang.annotation.*;
/**
* @author BlackDark
*/
@Target(value = {
ElementType.TYPE,
ElementType.METHOD,
ElementType.FIELD
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
//注解的参数:类型+参数名+默认值
String name() default "";
int value() default 0;
String [] values() default {};
}
四、反射
1.Class类
(1)Class本身是一个类,并且Class对象只能由系统创建
(2)一个加载的类,在JVM中只有一个对应的Class对象实例
(3)一个Class实例对应的是一个加载到JVM中的一个.class文件
(4)每个类的实例都会记录是由哪个Class实例产生的
(5)通过Class实例可以获取一个类所有被加载的结构
(6)Class是reflection的根源,对任何想要动态加载,运行的类,首先需要获取相应的Class对象
2.Class类的常用方法
3.获取Class的实例
五、java内存分析
1.堆
(1)存放new的对象和数组
(2)可以被所有线程共享,不会存放别的对象的引用
2.栈
(1)存放基本变量类型,包含这个基本变量的具体数值
(2)引用对象的变量,存放这个对象在堆内存中的具体地址
3.方法区(特殊的堆)
(1)包含所有的class和static变量
(2)可以被所有线程共享
六、类加载与ClassLoader的理解
(1)第一步:加载(Load)
将类的.class文件字节码内容加载到内存中,并将静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象。此过程由类加载器完成
(2)第二步:链接(Link),将java类的二进制代码合并到JVM的运行状态之中的过程
- 验证:确保加载的类的信息符合JVM规范,不存在安全方面问题
- 准备:正式为类变量分配内存并设置类变量默认初始值阶段,这些内存都将在方法区进行分配
- 解析:虚拟机内常量池引用(常量名)替换为直接引用(地址)的过程
(3)第三步:初始化(Initialize) - 执行类构造器方法的过程,类构造器方法是由编译期自动收集类中所有的类变量的赋值动作和静态代码块中的语句合并产生的,(类构造器是构造类信息的,不是构造该类对象的构造器)。
- 当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化
- 虚拟机会保证一个类的方法在多线程环境中被正确加锁和同步
七、什么时候发生类的初始化
(1)类的主动引用(一定会发生类的初始化)
- 虚拟机启动,先初始化main方法所在的类
- new一个类的对象
- 调用类的静态成员和静态方法
- 使用java.lang.reflect包的方法对类进行反射调用
- 当初始化一个类时,它的父类没有被初始化,则先初始化其父类
(2)类的被动引用(不会发生类的初始化) - 当访问一个静态域时,只有真正声明这个域的类才会被初始化
- 通过数组定义类引用,不会触发该类的初始化
- 引用常量不会触发此类的初始化(在链接阶段就已经存入了调用类的常量池中)