注解
- 注解:
Java.Annotation
Annotation 的作用
- 非程序本身,可以对程序做出解释
- 可以被其他程序读取
Annotation 的格式
- "@注释名" (可带参数名)
Annotation 使用范围
- 可附加在 package, class, method, field 等上面,可通过反射机制编程实现对这些元数据的访问
内置注解
@Override
: 重写注解@Deprecated
: 过时的@SuppressWarnings
: 抑制警告
自定义注解和元注解
元注解
- 负责注解其他注解
@Target
: 定义注解的作用目标@Retention
: 定义注解的保留策略@Documented
: 说明该注解将被包含在javadoc中@Inherited
: 说明子类可以继承父类中的该注解
自定义注解
public @interface 注解名(){}
反射机制
- 反射:
Java.Reflect
; Java 被视为动态语言的关键 - 反射机制允许程序在运行期间通过 Reflection API 获取任何类的内部信息,并能直接操作对象的内部属性和方法
- 特点:动态创建和编译类,具有较大的灵活性
静态和动态语言
-
动态语言: 可在运行时改变其结构的语言。
{
C#
,JavaScript
,PHP
,Python
...} -
静态语言: 运行时不可改变结构的语言
{
Java
,C
,C++
}Java 不是动态语言,但是Java可以称为 "准动态语言" 。即 Java有一定的动态性,可利用反射机制获得类似动态语言的特性。
特点
- 一个类在内存中只有一个 Class 对象
- 一个类被加载后,类的整个结构都会被封装在Class对象中
Class类
- Class 本身也是一个类
- Class 对象只能由系统创建对象
- 一个加载的类在JVM中只有一个Class实例
- 一个Class对象对应的是一个加载到JVM中的一个.class文件
- 每个类的实例都会记得自己是由哪个Class实例生成的
- 通过Class可以完整的获得一个类中所有加载的结构
- Class是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象
获取Class类的实例
1.Class clazz = 类名.class;
2.Class clazz = 实例.getClass();
2.Class clazz = Class.forName("类的全类名");
总结:只要元素和维度一样,就是同一个Class;
类加载内存分析
-
加载:将class文件字节码加载到内存中,并将静态数据转换成方法区的运行时数据结构,然后生成一个代表类的Class对象
-
链接:将Java类的二进制码合并到JVM的运行状态之中的过程
- 验证:确保加载的类信息符合JVM规范,没有安全问题
- 准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配
- 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
-
初始化
- 执行类构造器
方法的过程。 - 当初始化一个类的时候,如发现父类未初始化,则需要先初始化父类
- 虚拟机会保证一个类的
方法在多线程环境中被正确加锁和同步
类初始化
- 虚拟机启动,先初始化main方法所在的类
- new
- 父类未被引用,优先加载父类
- 调用类的静态成员(除了final常量)和静态方法、
- 使用
java.lang.reflect
包的方法对类进行反射
- 执行类构造器