Java注解和反射
Kang Lv3

注解

Annotation:不是程序本身,可以对程序作出解释

1
@注释名

内置注解

  • @Override:重写
  • @Deprecated:不推荐使用
  • @SuperessWarnings:警告

元注解

负责注解其他的注解

  • @Target:用于描述注解的使用范围
  • @Retention:用于描述注解的生命周期
  • @Documented:说明该注解将被包含在javadoc中
  • @Inherited:说明子类可以继承父类中的该注解

自定义注解

  • @interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class 注解 {
@MyAnnotation1(name = "kang")
public void test1() {}

@MyAnnotation2("kang")
public void test2() {}
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
// 注解的参数:参数类型+参数名();
String name();
int age() default 0;
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2 {
// 一个参数时,默认使用value
String value();
}

反射

Reflection,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。

理解Class类并获取Class实例

获取class实例方法

  • 已知具体的类,通过类的class属性获取,该方法最安全可靠,程序性能最高
1
2
// Person类
Class c1 = Person.class;
  • 已知某个类的实例,调用该实例的getClass()方法获取class对象
1
2
// 创建的一个person对象
Class c2 = person.getClass();
  • 已知一个类的全类名,且该类在类路径下,通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
1
2
// 路径
Class c3 = Class.forName("com.kang.test");

哪些类型可以有Class对象

一个类型只有一个class对象

  • class:外部类,成员,局部匿名类匿名内部类
  • interface:接口
  • []:数组
  • enum:枚举
  • annotation:注解
  • primitive:基本数据类型
  • void

类的加载与ClassLoader

  1. 加载
    • 将class文件字节码内容加载到内存中,并对这些静态数据转换成方法区的的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象
  2. 链接
    • 验证
    • 准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配
    • 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
  3. 初始化
    • 执行类构造器()方法的过程,将所有类变量的赋值动作和静态代码块的语句运行
    • 初始化一个类时,如果其父类还没有初始化,则先触发其父类的初始化
    • 虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步

Class对象能做设么

获取类的属性、方法和构造器

创建运行时类的对象

  • 调用Class对象的newInstance对象
    • 类必须有一个无参构造器
    • 类的构造器的访问权限需要足够

获取运行时类的完整结构

调用运行时类的指定结构

获得注解

  • getAnnotations();
  • getAnnotation();
  • 本文标题:Java注解和反射
  • 本文作者:Kang
  • 创建时间:2021-04-10 15:40:22
  • 本文链接:ykhou.github.io2021/04/10/Java注解和反射/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!