注解和反射

注意
本文最后更新于 2022-06-07,文中内容可能已过时。

注解(Annotation)

1. 什么是注解

格式:@注解名

image-20220606210449837

​ 例如: 重写的toString()用到的@Override就是一个注解。

1.1 内置注解

  • @Override:重写基类中的方法
  • @Deprecated:不推荐使用
  • @SuppressWarnings: 压制警告

image-20220606215557996

1.2 元注解

元注解的作用就是负责注解其他注解

image-20220606215856901

1.3 自定义注解

image-20220606221550743

注解的定义格式:public @interface 注解名{内容}

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@Documented // 表示是否将我们的注解生成在JavaDoc中
@Retention(RetentionPolicy.RUNTIME)	// 表示我们的注解在什么地方还有效
@Target(ElementType.ANNOTATION_TYPE) // 表示我们的注解可以用在哪些地方
@Inherited //子类可以继承的注解
public @interface MyAnnotation {
    System.out.println("MyAnnotation");
    //注解的参数:参数类型 + 参数名() [default 默认值];  如果默认值为-1,代表不存在。
    //参数类型:基本数据类型、枚举
    String name() default "张三";
    //只有一个参数建议用value命名
    String value() default "只有一个参数使用value命名"
}

// 在使用注解时,参数有默认值,可以不用赋值,没有默认值的需要我们赋值

Retention(作用域): runtime > class > sources

反射机制(Reflection)

演示一

image-20220606223140801

演示二

image-20220606223525291

反射机制研究及应用

image-20220606223935356

反射的优缺点

image-20220606224049710

反射相关的主要API

image-20220606224208951

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package cc.hiifong.demo
    
// 什么叫反射
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException{
        //通过反射获取类的Class对象
        Class c1 = Class.forName("cc.hiifong.demo.Demo");
        Class c2 = Class.forName("cc.hiifong.demo.Demo");
        Class c3 = Class.forName("cc.hiifong.demo.Demo");
        Class c4 = Class.forName("cc.hiifong.demo.Demo");
        
        // 一个类在内存中只有一个Class对象
        // 一个类被加载后,类的整个结构都会被封装在Class对象中。
        System.out.println(c1.hashCode);
        System.out.println(c2.hashCode);
        System.out.println(c3hashCode);
        System.out.println(c4.hashCode);
    }
}

// 输出的哈希值都是一样的


// 实体类

class Student {
    private String ID;
    private String name;
    private int age;

    public Student() {
    }

    public Student(String ID, String name, int age) {
        this.ID = ID;
        this.name = name;
        this.age = age;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return ID + '\t' + name + '\t' + age;
    }
}

Class类

image-20220606225622498

image-20220606225754929

Class类的常用方法

image-20220606230014800

获取Class类的实例

image-20220606230128937

实例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 测试class类的创建方式有哪些
public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("这个人是:" + person.name);

        //  方式一:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());

        //  方式二:forName获得
        Class c2 = Class.forName("Student");
        System.out.println(c2.hashCode());

        //  方式三:通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3);

        //  方式四:基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        // 获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}

class Person {
    public String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }
}

class Student extends Person{
    public Student(){
        this.name = "学生";
    }
}

class Teacher extends Person{
    public Teacher(){
        this.name = "老师";
    }
}

……

0%