第十三节 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
- 定义一个描述星期一到星期天的枚举类
- 定义一个方法,传入枚举对象,判断是星期几
定义枚举类:
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及以后版本引入的一个特性,与类、接口、枚举是在同一个层次,它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行 说明,注释。
注解按照作用可以分为三类:
- 编写文档:通过代码里标识的元数据生成文档【生成doc文档】
- 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
- 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】重点
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(){}