424-435枚举/注解

一、枚举

package com.alice.innerclass_.innerclass02;

// 如果希望在以后在这个地方生成自己的一些信息
/*
    比如这个代码的作者是谁
    这个代码的版本是谁
    可以在设置中的Editor中的File and Code Templates的Includes的File Header中修改
    将自己的版权,以及一些信息写上去
 */
public class EnumAndAnnotation01 {
    public static void main(String[] args) {
        // 使用
        Season spring = new Season("春天", "温暖");
        Season winter = new Season("冬天", "寒冷");
        Season summer = new Season("夏天", "炎热");
        Season autumn = new Season("秋天", "凉爽");
        // 假如现在又乱增加了一个季节,对于季节而言,值或者对象是固定的
        // 不会有更多的季节,因为它可以随便增加,破坏了这个类设计的初衷
        // 这种设计不能体现季节是固定的四个对象,因此这样的设计不合理
        // 我们希望这个类就是四个对象,自己创建好
        // 并且当前还能够通过set方法随便更改
        // 所以传统的方式写不合适。
        // 因此需要引入枚举类,即把具体的对象一个个的列举出来的类,就称为
        // 枚举类
        // 总结:
        // 创建Season对象有如下的几个特点
        // 1、季节的值是有限的几个值(spring,summer,autumn,winter)
        // 2、只读,不需要修改
        /*
            解决方案:枚举
         */
        Season other = new Season("xxx", "yyy");
    }
}
class Season {  // 类
    private String name;
    private String desc;  // 描述
    // 构造器

    public Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    // get set
    public String getName() {
        return name;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

/*
    进入第十一章-枚举和注解
    在枚举和注解这章要讲解:
        自定义类实现枚举
        enum关键字实现枚举
        JDK内置的基本注解类型
            @override
            @deprecated
            @suppresswarnings
        元注解:对注解进行注解
    一、由一个需求引出枚举类型
    要创建季节Season对象,请设计并完成。
    Enumeration

 */
 
 
 
// 02
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class Enum02 {
    public static void main(String[] args) {
        // 第一步将构造器私有,防止new
        // 第二步去掉set相关的方法,防止属性被修改
        // 第三步在类内部创建固定的对象
        // 第四步使用,
        System.out.println(SeasonCopy.AUTUMN);
        System.out.println(SeasonCopy.SPRING);
        System.out.println(SeasonCopy.SUMMER);
        System.out.println(SeasonCopy.WINTER);
        /*
            总结:
            1、不需要提供set方法,因为枚举对象值通常是只读
            2、对枚举对象/属性进行使用,使用final+static共同修饰,实现底层的优化
            3、枚举对象名通常需要使用全部大写,常量的命名规范
            4、枚举对象根据需要,也可以有多个属性
         */
    }
}
class SeasonCopy {  // 类
    private String name;
    private String desc;  // 描述

    // 定义了四个对象,这个时候已经可以使用了
    public static final SeasonCopy SPRING = new SeasonCopy("春天", "温暖"); // 创建固定的对象
    public static final SeasonCopy WINTER = new SeasonCopy("冬天", "寒冷"); // 创建固定的对象
    public static final SeasonCopy SUMMER = new SeasonCopy("夏天", "炎热"); // 创建固定的对象
    public static final SeasonCopy AUTUMN = new SeasonCopy("秋天", "凉爽"); // 创建固定的对象

    // 构造器
    private SeasonCopy(String name, String desc) {  // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
        this.name = name;
        this.desc = desc;
    }

    // get  步骤二 去掉set相关方法,防止属性被修改
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "SeasonCopy{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

/*
    解决方案-枚举
    1、枚举对应英文Enumeration,简写为Enum
    2、枚举是一组常量的集合
    3、可以理解为:枚举属于一种特殊的类,里面只包含一组有限的特定的对象

    而枚举有两种实现方式
    第一种是自定义类实现枚举
    第二种是使用enum关键字实现枚举
 */


// 03
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class Enum03 {
    public static void main(String[] args) {
        System.out.println(SeasonCopyEnum.SPRING);
        System.out.println(SeasonCopyEnum.WINTER);
        System.out.println(SeasonCopyEnum.SUMMER);
        System.out.println(SeasonCopyEnum.AUTUMN);
    }
}

/*
    第二种实现枚举的方式是使用关键字
 */
enum SeasonCopyEnum {  // 类 ,将其修改成Enum的步骤一----->将class更换成为enum
//    private String name;
//    private String desc;  // 描述

    // 定义了四个对象,这个时候已经可以使用了
    // 如果使用enum这个关键字来实现枚举-----步骤二将创建的固定对象直接  常量名(参数);
    // 如果有多个使用逗号间隔即可。
    // 如果使用枚举,要求常量对象写道最前面
//    public static final Season SPRING = new Season("春天", "温暖"); // 创建固定的对象
//    public static final Season WINTER = new Season("冬天", "寒冷"); // 创建固定的对象
//    public static final Season SUMMER = new Season("夏天", "炎热"); // 创建固定的对象
//    public static final Season AUTUMN = new Season("秋天", "凉爽"); // 创建固定的对象
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"),
    SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽");
    private String name;
    private String desc;  // 描述

    // 构造器
    private SeasonCopyEnum(String name, String desc) {  // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
        this.name = name;
        this.desc = desc;
    }

    // get  步骤二 去掉set相关方法,防止属性被修改
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "SeasonCopyEnum{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

// 04
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class EnumDetail04 {
}
enum SeasonCopyEnum04 {  // 类 ,将其修改成Enum的步骤一----->将class更换成为enum
//    private String name;
//    private String desc;  // 描述

    // 定义了四个对象,这个时候已经可以使用了
    // 如果使用enum这个关键字来实现枚举-----步骤二将创建的固定对象直接  常量名(参数);
    // 如果有多个使用逗号间隔即可。
    // 如果使用枚举,要求常量对象写道最前面
//    public static final Season SPRING = new Season("春天", "温暖"); // 创建固定的对象
//    public static final Season WINTER = new Season("冬天", "寒冷"); // 创建固定的对象
//    public static final Season SUMMER = new Season("夏天", "炎热"); // 创建固定的对象
//    public static final Season AUTUMN = new Season("秋天", "凉爽"); // 创建固定的对象
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"),
    SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽"),
    What(), How; // 这里就是调用的无参构造器,还可以去掉小括号
    private String name;
    private String desc;  // 描述

    // 构造器
    private SeasonCopyEnum04(String name, String desc) {  // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
        this.name = name;
        this.desc = desc;
    }

    SeasonCopyEnum04() {}  // 无参构造器

    // get  步骤二 去掉set相关方法,防止属性被修改
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "SeasonCopyEnum{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
/*
    1、当我们使用enum关键字开发一个枚举类的时候,默认会继承Enum类
    等会要使用一个工具来证明,javap工具
    如果开发了一个Java文件,Hello.java
    使用了一个编译工具Javac,生成Hello.class
    通过Javap可以反编译成为Java文件,因为上一个文件使用过枚举,我们在
    Out文件夹中的可以根据当前包找到对应的class文件,
    即SeasonCopyEnum.class文件 Show in Explorer,在资源管理器中打开
    然后cmd
    javap SeasonCopyEnum.class
    Compiled from "Enum03.java"
    final class com.alice.innerclass_.innerclass02.SeasonCopyEnum extends java.lang.Enum
    <com.alice.innerclass_.innerclass02.SeasonCopyEnum> {
      public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum SPRING;
      public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum WINTER;
      public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum SUMMER;
      public static final com.alice.innerclass_.innerclass02.SeasonCopyEnum AUTUMN;
      public static com.alice.innerclass_.innerclass02.SeasonCopyEnum[] values();
      public static com.alice.innerclass_.innerclass02.SeasonCopyEnum valueOf(java.lang.String);
      public java.lang.String getName();
      public java.lang.String getDesc();
      public java.lang.String toString();
      static {};
    }
    可以看到当前这个class文件编译自Enum03.java
    继承了java.lang.Enum
    并且是一个final的类
    定义的四个常量对象还是static final的
    还有一些隐藏的
    以上说明了
    当我们使用enum关键字开发一个枚举类的时候,默认会继承Enum类
    而是一个final类
    2、传统的public static final Season2 SPRING = new Season2("春天", "温暖");
    简化成了SPRING("春天","温暖");
    这里必须要知道,它调用的是哪个构造器
    3、如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
        What(), How; // 这里就是调用的无参构造器,还可以去掉小括号
    4、当有多个枚举对象的时候,使用逗号间隔,最后一个有分号结束
    5、枚举对象必须放到枚举类的行首
 */
 
// 05
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class EnumTest05 {
}

/**
 * 第一题
 *  下面代码是否正确,并说明表示的含义?
 */
enum Gender {  // 正确,使用关键字实现枚举类
    BOY, GIRL; // 正确,调用了Gender的默认无参构造器
}

/**
 * 第二题
 * Gender2 boy = Gender2.BOY;
 * Gender2 boy2 = Gender2.BOY;
 * System.out.println(boy);  // 这里的本质就是调用Gender2的父类的toString方法
 *         // 前面说过,这里会继承一个叫做java.lang.Enum的这个类
 *         // 看这个的父类是如何定义的,而这里的父类其实就是return name
 *         // 所以这里输出的是BOY
 * System.out.println(boy2 == boy);  // T,因为枚举是静态的,所以是同一个对象
 * 相当于
 * final class Gender2 extends Enum<Gender2> {
 *     public static final Gender2 BOY = new Gender2("BOY", 0);
 *     public static final Gender2 GIRL = new Gender2("GIRL", 1);
 *     // ...
 * }
 * 所以返回的是名字BOY
 */
enum Gender2 {
    BOY, GIRL;
}


// 06

package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class EnumMethod06 {
    public static void main(String[] args) {
        SeasonCopyEnum06 autumn = SeasonCopyEnum06.AUTUMN;  // 得到一个枚举对象
        System.out.println(autumn.name());  // 可以获得当前枚举对象的名称
        System.out.println(autumn.ordinal());  // 输出的是该枚举对象的次序,也就是第几个,默认从零开始编号
//        SeasonCopyEnum06.values();  // 这里values隐藏起来了,源码中没有这个
        // 可以从反编译可以看到返回的是一个数组,该数组含有定义的所有枚举对象。
        SeasonCopyEnum06[] values = SeasonCopyEnum06.values();
        for (int i = 0; i < values.length; i++) {
            System.out.print(values[i] + " ");
        }
        System.out.println();
//        或者使用增强for循环
        for (SeasonCopyEnum06 value: values) {  // 就是不断从数组中直接取出元素怼到value中
            System.out.print(value.name() + " ");
        }
        System.out.println();
        SeasonCopyEnum06 autumn1 = SeasonCopyEnum06.valueOf("AUTUMN");
//        SeasonCopyEnum06 autumn1 = SeasonCopyEnum06.valueOf("XXX");  // 找不到会报错
        // valueOf是将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常
        // 先根据你输入的名称到SeasonCopyEnum06的枚举对象查找,如果找到就返回
        // 如果没有找到就报错
        System.out.println("autumn1=" + autumn1);
        System.out.println(autumn == autumn1);  // 这两个指的是同一个枚举对象
        System.out.println(SeasonCopyEnum06.AUTUMN.compareTo(SeasonCopyEnum06.SUMMER));
//        return self.ordinal - other.ordinal;
        // 将两个枚举类型的编号进行比较,直接看最关键的部分就是使用这两个编号进行减3-2

        /*
            总结:
               1、toString:Enum类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息。
               2、name可以返回当前对象名,子类中不能重写
               3、ordinal:返回当前对象的位置,默认从零开始
               4、valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常。
               5、values:返回当前枚举类中所有的常量
               6、compareTo,比较两个枚举常量,比较的是编号。
         */
    }
}
enum SeasonCopyEnum06 {
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"),  // 01
    SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽");  // 23
    private String name;
    private String desc;  // 描述

    // 构造器
    private SeasonCopyEnum06(String name, String desc) {  // 步骤一 构造器这里不希望别人去new对象,所以做成私有的
        this.name = name;
        this.desc = desc;
    }

    SeasonCopyEnum06() {}  // 无参构造器

    // get  步骤二 去掉set相关方法,防止属性被修改
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "SeasonCopyEnum{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
/*
    说明:使用关键字enum时,会隐式继承Enum类,我们就可以使用Enum类的相关方法
 */
 
// 07
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class EnumExercise07 {
    public static void main(String[] args) {
        // 获取到所有的枚举对象,即返回数组
        Week[] weeks = Week.values();
        // 遍历输出
        System.out.println("===所有星期的信息如下===");
        for (Week week : weeks) {
            System.out.println(week);
        }
    }
}

enum Week {
    // 定义Week的枚举对象
    MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"),
    FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期天");
    private String name;
    private Week(String name) {  // 不能new创建对象设置为private
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}
/*
    1、声明Week枚举类,其中包含星期一到星期日的定义;
    MONDAY
    TUESDAY
    WEDNESDAY
    THURSDAY
    FRIDAY
    SATURDAY
    SUNDAY
    2、使用values返回所有枚举数组,并遍历,输出
 */
// 08
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */


/*
    enum实现接口
    1、使用enum关键字之后,就不能再继承其他类了,因为enum会隐式继承Enum,
    Java是单继承机制。
    2、枚举类和普通类一样,可以实现接口,如下的形式
    enum 类名 implements 接口1,接口2{}

 */

//// 1、错误写法
//class A {
//
//}
//enum Season3 extends A {
//
//}

// 2、依然可以实现接口
public class EnumInterface08 {
    public static void main(String[] args) {
        Music.CLASSICMUISC.playing();
    }
}
interface IPlaying {
    public void playing();
}
enum Music implements IPlaying{
    CLASSICMUISC;

    @Override
    public void playing() {
        System.out.println("播放好听的音乐。");
    }
}

二、注解(了解)

// 09
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class Annotation09 {
    public static void main(String[] args) {

    }
}
class Father {
    public void fly() {
        System.out.println("Father fly...");
    }
}
class Son extends Father {
    @Override // 1这个注解放到了fly方法上面,表示子类的fly方法重写了父类的fly
    public void fly() {
        // 2如果这里没有写这个注解也还是重写了父类的fly
        // 3要这个东西有什么用呢?这个Override的价值在什么地方?
        // 如果写了这个注解,编译器就会检查是否真的重写了,如果确实重写了则编译通过,如果没有构成重写,则编译错误
        System.out.println("Son fly...");
    }
//    @Override
//    public void say() {}  // 这里没有构成重写所以这里会有一个红色波浪线,你编译的时候就要报错。
    // 相当于是一个检查,这里父类根本就没有这个方法
    /*
    public @interface Override {
}
看到源码是这样的一个东西,这里的@interface表示是一个注解类,而不是接口
也就是@interface不是interface,是一个注解类,在JDK5.0的时候进入进去的。
     */
}
/*
    1注解Annotation也被称为元数据Metadata,用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。
    2和注释一样,注解不会影响程序逻辑,但注解可以被编译或者运行,相当于嵌入在代码中的补充信息。
    3在JavaSE中,注解的使用目的比较简单,例如标记过失的功能,忽略警告等。在JavaEE中注解占据了更加重要的角色,
    例如用来配置应用程序的任何切面,代替Java EE旧版中所遗留的繁冗代码和XML配置等。

    使用Annotation时要在其前面增加@符号,并且将该Annotation当成一个修饰符使用,用于修饰它支持的程序元素
    三个基本的Annotation:
    1、@Override:限定某个方法,是重写父类方法,该注解只能用于方法
    2、@Deprecated:用于表示某个程序元素(类,方法等)已过时。
    3、@SuppressWarnings:抑制编译器警告。
 */

// 10
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */


/*
    Override使用说明
    1、@Override表示指定重写父类的方法(从编译层面验证),如果父类中没有fly方法,则会报错
    2、如果不写@Override注解,而父类仍有public void fly() {},仍然构成重写。
    3、@Override只能修饰方法,不能修饰其他类,包,属性等等
    4、查看@Override注解源码为
    @Target(ElementType.METHOD),说明只能修饰方法
    5、@Target是修饰注解的注解,称为元注解

 */
class AA {
    void a() {}
}
//@Override  // 只能修饰方法,因为底层源码
class BB extends AA {
    /*
        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.SOURCE)
        public @interface Override {
        }
        底层源码说明元素类型是一个METHOD,只能修饰方法
        而使用这个Target修饰了注解,说明这是一个元注解
     */
    @Override
    void a() {
        super.a();
    }
}

public class Annotation10 {
    public static void main(String[] args) {
//        A a = new A();  // 这里会出现删除线
        A a = new A();  // 虽然过时了但是仍然可以使用只是不推荐使用
        a.hi();
        System.out.println(a.n1);
    }
}
// @Deprecated,使用这个修饰一个类,表示这个类已经过时了。
// 当我们使用这个类用来创建对象的时候,这个时候就会出现删除线
// @Deprecated可以修饰某个元素,表示这个元素已经过时了,不仅仅可以修饰类
// 即使不推荐使用,但是仍然可以使用
/*
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    public @interface Deprecated {
    }
    这个是这个注解的源码,这个源码中的确是一个注解,为什么呢?因为使用的是@interface来进行修饰
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    这里指明了可以在什么地方使用这个注解
    构造器,字段,局部变量,方法,包,参数,类,这里的TYPE指的是class类
    除此之外其他的地方不能使用了
    这个注解可以用来做一个过度
    比如我们这里JDK8,以后可能升级到JDK11
    在JDK8中写的代码中有一个类,比如说是A类,如果以后要升级到JDK11是一个B类
    就可以告诉一下
    即:版本升级

    小结:
        @Deprecated
        1、用于表示某个程序元素(类或者方法等)已经过时了
        2、可以修饰方法,类,字段,包,参数等等
        3、@Target(value={CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,
        PACKAGE,PARAMETER,TYPE})
        4、@Deprecated的作用可以做到旧版本的兼容和过渡。
 */
@Deprecated
class A {
    @Deprecated
    public int n1 = 10;  // Deprecated修饰成员变量
    @Deprecated
    public void hi() {  // Deprecated不仅仅可以修饰类,还可以修饰其他的,比如方法,在使用这个方法的时候就会出现删除线
        System.out.println("你好,这里是A中的方法hi()"); // 但是仍然可以使用
    }
}

// 11
package com.alice.innerclass_.innerclass02;

import java.util.ArrayList;
import java.util.List;


/**
 * @author alice_huijing
 * @version 1.0
 */
//@SuppressWarnings({"rawtypes", "unchecked", "unused"})  // 直接给类添加抑制信息
public class Annotation11 {
    @SuppressWarnings({"rawtypes", "unchecked", "unused"})  // 在大括号中可以写入希望抑制的,也就是不显示的警告信息
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("A");  //0
        list.add("B");  //1
        list.add("C");  //2
        int i;
        System.out.println(list.get(1));
        /*
            当我们不想看到这些警告的时候,可以使用SuppressWarnings注解抑制这些警告信息
            具体可以抑制哪些信息,老韩提供了一个文档
            SuppressWarning中的属性介绍以及属性的说明.txt
            比如all可以抑制所有的警告,原本有六个警告,全部写上去之后这些警告就直接消除了。
            我们可以将鼠标放到这些黄色的部分看看出现什么警告,对应出现的警告,可以在文档中
            查找到对应的抑制功能,做到精确的抑制
            比如List list = new ArrayList();这里是一个
            Raw use of parameterized class 'ArrayList'
            从这里我们可以发现有一个Raw的单词
            我们可以使用rawtypes来抑制,这里和泛型有关系,等讲到泛型的时候还会讲解。

            再比如后面的add
            这里没有进行类型的检查
            Unchecked call to 'add(E)' as a member of raw type 'java.util.List'
            只需要填入unchecked

            还有一个警告
            Variable 'i' is never used
            i这个没有使用
            可以使用unused来抑制

            关于这个的作用范围和你放的位置有关
            现在将这个放到main方法上面,这个作用的范围就是再main方法中

            如果写另外一个方法f1,这里就管不住了。
            当然我们可以采取同样的操作进行抑制
            直接添加注解即可。

            如果想要将这个类中的所有警告全部抑制,只需要给类添加即可。
            @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
            @Retention(RetentionPolicy.SOURCE)
            public @interface SuppressWarnings {
                String[] value();
            }
            我们可以放到类,字段,方法,参数。。
            这里的value表示传的时候可以传一个数组进去。
            可以指定多种要抑制的数据
         */
    }
    public void f1() {  // 因为管的是main,所以这里直接提出警告,另外这个注解是可以放到一条语句上面的。
        @SuppressWarnings({"rawtypes"})
        List list = new ArrayList();
        list.add("A");  //0
        list.add("B");  //1
        list.add("C");  //2
        @SuppressWarnings({"unused"})
        int i;
        System.out.println(list.get(1));
    }
}

// 在平时我们写代码的时候会容易出现一些警告信息,这些警告并不是说我们的代码不能使用了,依然可以运行

/*
    小结:
    1、unchecked是忽略没有检查的警告
    2、rawtypes是忽略没有指定泛型的警告,传参的时候没有指定泛型的警告
    3、unused是忽略没有使用某个变量的警告错误
    4、@SuppressWarnings可以修饰的程序元素为,查看@Target
    5、生成@SupperssWarnings时,不用背,直接点击左侧的黄色提示就可以选择(注意可以指定生成的位置)。
 */
// 12
package com.alice.innerclass_.innerclass02;

/**
 * @author alice_huijing
 * @version 1.0
 */
public class Annotation12 {
    public static void main(String[] args) {

    }
}
class OO {
    public void xx() {
        System.out.println("OO xx");
    }
}
@Deprecated
class O extends OO{
    @Deprecated
    public int n1 = 10;
    @Override
    public void xx() {
        System.out.println("O xx");
    }
    /*
        这里的Override的策略就是
        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.SOURCE)
        public @interface Override {
        可以看到策略是SOURCE,所以只是在编译器层面,或者说是源码的层面生效
        }

        点到这里的Target中看
        @Documented
        @Retention(RetentionPolicy.RUNTIME)
        @Target(ElementType.ANNOTATION_TYPE)
        public @interface Target {
            ElementType[] value();
        }
        看到ElementType中,可以支持这些程序元素
        public enum ElementType {
            TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,
            ANNOTATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE
        }

        @Deprecated
        比如像这种很多地方都可以使用
        但是@Override在类上面不能使用
        因为@Target(ElementType.METHOD),Override只允许在方法层面
        而@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
        可以在TYPE,也就是可以在类上
     */
}
/*
    有关JDK的元Annotation,元注解的介绍
    元注解的基本介绍:
    JDK的元Annotation用于修饰其他Annotation
    元注解:本身作用不大,讲解这个的原因是希望大家看源码的时候就可以知道他是干什么的。
    元注解的种类(使用不多,了解,不用深入研究)
    1、Retention //指定注解的作用范围,三种SOURCE,CLASS,RUNTIME,即源码,类型,运行时
    2、Target  // 指定注解可以在哪些地方使用
    3、Documented指定该注解是否会在Javadoc体现
    4、Inherited  // 子类会继承父类注解

    即:
    1)元注解是修饰注解的注解
    @Retention注解
    说明:
        只能用于修饰一个Annotation定义,用于指定该Annotation可以保留多长时间,
        @Retention包含一个RetentionPolicy类型的成员变量,使用@Rentention
        时必须为该Value成员变量指定值:
        @Retention的三种值
        1、RetentionPolicy.SOURCE:编译器使用之后,直接丢弃这种策略的注解
        2、RetentionPolicy.CLASS:编译器将把注解记录在class文件中,当运行Java程序时,
        JVM不会保留注解,这是默认值。
        3、RetentionPolicy.RUNTIME:编译器将把注解记录在class文件中,当运行Java程序时
        ,JVM会保留注解,程序可以通过反射获得该注解。
        这里给出一张图
    @Target
    这里基本说明
    用于修饰Annotation定义,用于指定被修饰的Annotation能用于修饰哪些程序元素,@Target也包含一个名为
    value的成员变量


    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    public @interface Deprecated {
    }
    在Deprecated中有@Documented,到时候生成JavaDOC这里的Deprecated会保留到生成的Java文档上
    比如在String这个类里面有一个过时的方法
    比如getBytes,这个方法上面会显示有@Deprecated

    @Inherited注解
    被它修饰的Annotation将具有继承的特性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解

 */

三、附图

image

posted @ 2025-05-15 22:16  请叫我虾  阅读(12)  评论(0)    收藏  举报