第十三节 Java 枚举与注解

  • 1. 枚举
  • 1. 1 枚举特征
  • 2. 使用枚举
  • 2.1 定义枚举类
  • 3. 注解
  • 3.1 注解的介绍
  • 3.2 JDK 内置注解
  • 3.3 定义注解
  • 3.4 元注解
  • 3.5 注解的属性


1. 枚举

1. 1 枚举特征

枚举是Java 1.5出来之后新增的类型,它可以用来定义一组取值范围固定的变量。
在枚举没有出来之前,要定义这样的变量,往往通过定义一个接口,将不同的变量使用不同的整数赋值,但是这样存在明显缺点:
1)不能保证其定义数值的合法性;
2)无法根据数值大小获取其含义

枚举有如下特征:
1)Enum类是枚举的一个封装类,是所有类型的超类,它是一个没有抽象方法的抽象类
2)通过关键字enum,可以定义枚举类型
3)Enum类中定义了很多常用的方法
如元素之间的比较,获取元素名称,获取元素定义的次序等
a. compareTo(E o):比较枚举元素的顺序
b. eauqls(Object o):判断枚举元素是否相同
c. name():获取元素定义时的名称
d. ordinal():获取枚举元素被定义时的顺序,从0开始计算
注意:对于枚举可以使用“==”来比较两个枚举元素相同与否,由于它们已经重写了equals()和hashCode()两个方法

2. 使用枚举

2.1 定义枚举类

1)语法结构

修饰符 enum 枚举类名称{
枚举值1,枚举值2,枚举值3.....}

2)定义一个数据库产品的枚举类

public enum DBType {
    MySQL,ORACLE,DB2;
}

public class DBTypec {
    public final static DBTypec MYSQL=new DBTypec();
    public static final DBTypec DB2=new DBTypec();
    public final static DBTypec ORACLE=new DBTypec();

    @Override
    public String toString() {
        return "**************";
    }
}

3)使用

public class EnumTest {
    public static void main(String[] args) {
        System.out.println(DBType.DB2.toString());
        System.out.println(DBType.MySQL);
        System.out.println(DBType.ORACLE);
        System.out.println("------使用类去定义-----");
        System.out.println(DBTypec.DB2);
        System.out.println(DBTypec.MYSQL);
        System.out.println(DBTypec.ORACLE);
    }
}

3)注意事项
a. 每一个枚举值都是该枚举类的一个对象;
b. 枚举类的构造方法都是私有的;
c. 在枚举类中,所有的枚举对象以大写的形式存在,枚举对象之间以逗号隔开;
d. 枚举对象要定义在枚举类的第一行;
e.里面的量都是静态常量,会随着类的加载先加载,因此它的私有构造方法也会进行构造;
f. 默认的成员变量都是私有的;
4)案例1

  1. 定义一个描述星期一到星期天的枚举类
  2. 定义一个方法,传入枚举对象,判断是星期几
    定义枚举类:
public enum Week {
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}

使用:

public class WeekTest {
    public static void main(String[] args) {
        getWeekInfo(Week.FRIDAY);
    }
    public static void getWeekInfo(Week week){
        switch (week){
            case MONDAY:
                System.out.println("今天是星期一");
                break;
            case TUESDAY:
                System.out.println("今天是星期二");
                break;
            case WEDNESDAY:
                System.out.println("今天是星期三");
                break;
            case THURSDAY:
                System.out.println("今天是星期四");
                break;
            case FRIDAY:
                System.out.println("今天是星期五");
                break;
            case SATURDAY:
                System.out.println("今天是星期六");
                break;
            case SUNDAY:
                System.out.println("今天是星期日");
                break;
        }
    }
}

5)案例2

public enum Color {
    RED("红"),GREEN("绿"),BLUE("蓝");
    private String name;
    //增加一个带参数的构造方法
    Color(String name){
        this.name=name;
    }
    @Override
    public String toString() {
        return name;
    }
}

public class ColorTest {
    public static void main(String[] args) {
        displayColor(Color.GREEN);
    }
    public static void displayColor(Color color){
        switch (color){
            case RED:
                System.out.println(color);
                break;
            case GREEN:
                System.out.println(color);
                break;
            case BLUE:
                System.out.println(color);
                break;
        }
    }
}

3. 注解

3.1 注解的介绍

定义:注解(Annotation),也叫元数据,一种代码级别的说明,他是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次,它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行 说明,注释。

注解按照作用可以分为三类:

  1. 编写文档:通过代码里标识的元数据生成文档【生成doc文档】
  2. 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
  3. 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】重点

3.2 JDK 内置注解

1)@Override:用于修饰此方法重写了父类的方法
2)@Deprecated:用于修饰已经过时的方法
3)@SuppressWarnings:用于通知java编译器禁止特定的编译警告
3.1)@SuppressWarings(“unused”)

3.3 定义注解

注解通过@interface关键字进行定义。

public @interface 注解名称{....}

使用注解,以在类上使用注解为例:

@注解名称
public class Test{....}

3.4 元注解

元注解是可以通过注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其他的注解上面。
元注解有:@Retention、@Documented、@Target、@Inherited、@Repeatable 5种。
1)@Retention
Retention 的英文意思为保留期的意思。当@Retention应用到一个注解上的时候,它解释说明了这个注解的存活时间。
它的取值如下:


描述

RetentionPolicy.SOURCE

注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视

RetentionPolicy.CLASS

注解只被保留到编译进行的时候,它并不会被加载到JVM中

RetentionPolicy.RUNTIME

注解可以保留到程序运行的时候,它会被加载进入到JVM中,所以在程序运行时可以获取它们

注意:RetentionPolicy是一个枚举类

示例代码:

@Retention(RetentionPolicy.RUNTIME)//定义该注解在运行期有效
public @interface MyAnnotation{...}

2)@Target
Target是目标的意思,@Target 指定了注解运用的地方
2.1)ElementType.ANNOTATION_TYPE:可以给一个注解进行注解
2.2)ElementType.CONSTRUCTOR:可以给构造方法进行注解
2.3)ElementType.FIELD:可以给属性进行注解
2.4)ElementType.LOCAL_VARIABLE:可以给局部变量进行注解
2.5)ElementType.METHOD:可以给方法进行注解
2.6)ElementType.PACKAGE:可以给一个包进行注解
2.7)ElementType.PARAMETER:可以给一个方法内的参数进行注解
2.8)ElementType.TYPE:可以给一个类型进行注解,比如类,接口,枚举

代码示例:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)//这表示这个注解只能用在一个类型上,比如类,接口,枚举等
public @interface MyAnnotation{....}

3)Inherited
父类使用的注解如果声明了@Inherited,,则这个类可以继承注解

@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotion{...}

@MyAnnotation
public class A{...}
public class B extends A{...}//这个类可以继承A的注解

注意:注解MyAnnotation被@Inherited修饰后,之后类A被MyAnnotation注解,A的子类B也拥有MyAnnotation这个注解
4)@Documented
这个元注解是和文档有关,它的作用能够将注解中的元素包含到Javadoc中去。
5)@Repeatable
使用场景:
在需要对同一个注解多次使用在同一个类,接口,方法,属性等上面时,需要借助@Repeatable
代码示例:

@Repeatable(Person.class)
public @interface Person{String role() default "";}

@Person(role="CEO")
@Person(role="husband")
@Person(role="father")
@Person(role="son")
public class Man{String name="";}

3.5 注解的属性

注解的属性也叫做成员变量。“注解只有成员变量,没有方法”。
注解的成员变量在注解的定义中以 无参的方法 形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
int id();
String msg();
}

上面代码定义了@MyAnnotation 这个注解拥有id和msg两个属性,在使用的时候,我们应该给他们进行赋值,多个属性之间用逗号隔开。

@MyAnnotation(id="3",msg="hello annotation")
public class Test{...}

注解中属性可以有默认值,默认值需要用default关键字指定,比如:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
public int id() default -1;

如果一个注解内仅仅只有一个名字为value 的属性时,应用这个注解时可以直接将属性值填写到括号内:

public @interface Check{
String value();
}

上面代码中,Check这个注解只有value这个属性,所以可以这样应用:

@Check("hi")
int a;
等价于:
@Check(value="hi")
int a

最后,还需要注意的一种情况是一个注解没有任何属性,比如:

public @interface Perform{//没有属性}

//使用
@Perform
public void testMethod(){}