一、注解

学前疑惑:

  • 干啥用的?
  • 类似于注释,给编译器看的?看的什么东西呢。加载的时候会有什么不同?
  • 虽然语法上有点像 python 的装饰器,但是作用似乎不一样

1.1 什么是注解

  • 可以对程序作出解释(类似于注释,是给编译器看的)
  • 可以被其他程序(如编译器等)读取

1.2 元注解

用于注解其他注解的注解,即对注解进行一些说明。

共有4个 —— @Target, @Retention, @Document, @Inherited

  • @Target
    • 描述注解的使用范围,作用于方法、类等
  • @Retention
    • 表示注解在什么地方还有效
    • SOURCE < CLASS < RUNTIME
    • 默认用 RUNTIME
  • @Document
    • 表示是否将注解生成在 javadoc 中
  • @Inherited
    • 说明子类可以继承父类注解

1.3 自定义注解

1
2
3
4
5
6
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
@interface MyAnnotation {
String name() default "";
int age() default 0;
}
  • 使用 @interface 声明注解
  • 其中的每个方法,实际为一个配置参数
  • 如果只有一个参数成员,一般参数名为 value
  • 默认值用 default

二、反射机制

学前疑惑:

  • 什么是反射,有什么作用?
  • 为什么不直接new出来对象调用呢?

2.1 基础概念

2.1.1 相关知识

静态语言 & 动态语言:

  • 动态语言

    • 【在运行时检查】
    • 在运行时可以改变结构的语言,即变量、函数等可以在运行时改变类型(JS、Python 等)
  • 静态语言

    • 【在编译期检查】
    • 相对应的,不能改变类型,声明了类型就不许改变(Java、C++ 等)

强类型 & 弱类型:

  • 强类型
    • 【不会隐式做语言类型转换】
  • 弱类型
    • 【做隐式类型转换】

preview

2.1.2 反射概念

  • 反射机制允许程序在执行期间获取类本身的各种定义,如属性、方法等
  • 与new对象的方式相反:
    • new 对象:import 包 -> new 对象 -> 取得实例化对象
    • 反射:实例化对象 -> getCalss() 方法 -> 得到完整的”包类“名称
    • 由于和new对象的过程相反,所以有「反射」的叫法

2.1.3 反射的作用

  • 在运行时判断对象所属的类
  • 在运行时构造对象
  • 在运行时调用对象的成员变量和方法
  • 。。。

2.1.4 反射优点和缺点

优点:

  • 动态创建对象和编译

缺点:

  • 性能低
  • 反射类似于解释操作,告诉JVM我需要什么,然后JVM来做,会比我们直接操作要慢

2.2 反射

2.2.1 获取反射对象

  • 一个类在内存中只有一个Class对象
  • 一个类被加载后,整个类结构都会封装在 Class 对象中
1
Class c1 = Class.forName("com.shuofxz.reflection.User");

2.2.2 Class

  • 是什么

    • Class 本身也是一个类
    • Class 对象只能由系统(JVM)创建
  • 特征

    • 一个类只会在 JVM 中有一个 Class 实例
    • 每个类的实例都知道自己是由哪个 Class 实例生成
  • 用处

    • 通过 Class 实例可以获得一个类中所有被加载的结构
    • 通过 Class 可以动态加载运行类(即反射)
  • 获取 Class 类的实例

1
2
3
4
5
6
7
8
9
10
// 1) 从类获得
Class c1 = Person.class;

// 2) 从实例获得
Class c2 = person.getClass();

// 3) 通过 包名+类名 获得
Class c3 = Class.forName("com.shuofxz.Person");

// 4) ClassLoader
  • 类加载 与 ClassLoader
    • 详细请看 JVM 篇
      1. 方法区:从 .class 文件中加载类数据到方法区(每个类数据包括静态变量、静态方法、常量池、代码等)
      2. 堆:以方法区类数据作为模板,生成出类对象;再由「类对象」生成出「对象」
      3. 栈:程序执行,按照代码赋值对象,执行方法

三、注解与反射

  • 注解可以通过反射机制起作用

    • 获取到一个类实例后,通过反射的方式拿到所写的注解信息
    • 再通过类本身信息 + 注解的信息 完成一些操作
      • 如操作数据库的时候,会给类属性对应一个数据库列的名字,就可以用注解来对应
    • 相当于一个语法糖?
      • 将一些本该由更多代码实现的对应信息,通过注解简单的方式实现了
  • 作用

    • 简化代码

    • 结偶

      • 比方原来需要通过继承或者实现方式获得的属性和方法,通过注解方式结偶