Egoistic_Flowers

Java注解与反射
Java注解与反射

f0f30996658f45427a3c7ee6d36c24e6

Java注解与反射

1 注解

Annotation的作用:

  • 不是程序,但是是对程序做解释(与注释相同)
  • 可以被其他程序读取

Annotation的格式:

  • @注解(valuse="")

1.1 内置注解

  • @Override 只能用于修饰方法,表示此方法重写父类的方法
  • @Deprecated 已过时,提示此方法有更好的替代方法,建议使用替代的方法
  • @SuppressWarnings 镇压警告,抑制编译时产生的警告信息

1.2 元注解

元注解的作用是注解其他的注解

  • @Target:表示注解的使用范围(方法,类...)
  • @Retention:表示在什么级别保存注解信息(SOURCE CLASS RUNTIME)
  • @Documented:表示将注解生成在JAVAdoc中
  • @Inherited:表示子类可以继承父类的注解

1.3 自定义注解

参数为value可以省略参数名

2 反射机制

动态语言&静态语言

  • 动态语言:在运行时可以改变其结构的语言

    • C#,JavaScript,PHP,Python
  • 静态语言:运行时结构不能改变

    • Java,c,c++
  • Java是准动态语言,可以通过反射机制实现动态语言的特性

2.1 获取反射对象

Reflection

  • 反射机制允许程序在执行时,获取任何类的内部信息,并能直接操作任意内部属性及方法(动态的特性)
  • 加载完类后,在堆方法区中就产生了Class类的对象,Class对象包含了所有类的结构信息

获取class对象:

定义需要获取反射对象的类:

测试反射获取class对象:

获取各种类型的Class对象

2.2 类加载的内存分析

Java内存

  • 堆区:

    • new的对象,数组
    • 可以被所有的线程共享
    • 不会存放引用
  • 栈区:

    • 存放局部变量
    • 引用对象的变量(引用在堆区的地址)
  • 方法区:

    • 包含所有的class
    • 可以被所有的线程共享
    • 特殊的堆区

类的加载过程

  • 1.类的加载:将类的class文件读入内存,并为之创建一个Class对象,此过程由类加载器完成

  • 2.类的链接:将类的二进制数据合并到JRE中

    • 验证:确保类的信息符合JVM规范
    • 准备:为static变量分配内存,并设置默认值,在方法区中
    • 解析:将常量池的符号引用(常量名)替换为直接引用(地址)
  • 3.类的初始化:JVM负责类初始化

    • 执行类构造器方法,类构造器自动收集所有变量的赋值和静态代码块中的语句合并(不是对象构造器)
    • 初始化一个类的时候,如果发现父类没有初始化,会先将父类进行初始化
    • JVM保证每个类的类构造器方法在多线程环境正确加锁和同步

测试类的加载:

执行结果:

  • 创建A类的对象 A类静态代码块 A类无参构造器 100

类的加载过程:

  • 1.加载到内存,产生一个A类对应的Class对象

  • 2.链接,链接结束后 m=0

  • 3.初始化,类构造器方法将静态代码块合并,结果:

    • <clinit>(){

      System.out.println("A类静态代码块"); m = 300; m = 100;

      }

2.3 类初始化条件

类主动引用(发生类初始化)

  • JVM启动,初始化main方法所在的类
  • new一个类的对象
  • 调用类的静态成员变量或静态方法
  • 使用反射方式对类进行反射调用
  • 初始化一个类会先初始化它的父类

类的被动引用(不发生类的初始化)

  • 访问一个静态作用域,只有声明这个域的类会被初始化(子类用父类的静态方法,子类不会初始化)
  • 通过数组定义引用,不会触发类初始化
  • 引用常量不会触发类初始化(链接阶段已经进入常量池)

测试类的初始化:

2.4 类加载器

  • 类加载器的作用:将class文件字节码加载到内存中,将静态数据转换成方法区的运行时数据结构,在堆区生成Java.lang.Class对象,作为方法区中类数据的访问入口
  • 类缓存:某个类加载到类加载器中,会维持加载一段时间,JVM垃圾回收机制会回收Class对象

类加载器种类

  • 引导类加载器:JVM自带类加载器,装载核心类库,C++编写,无法直接获取
  • 扩展类加载器:负责jre/lib/ext目录下的jar包或指定目录下的jar包装入工作库
  • 系统类加载器:负责java -class path或指定目录jar包装入,最常用类加载器

2.5 获取运行时类的信息

2.6 动态创建对象

2.7 反射获取泛型

2.8 反射获取注解

posted on 2021-12-02 17:48  Egoistic_Flowers  阅读(37)  评论(0编辑  收藏  举报