13.1、枚举类
13.1.1、概述
概述:枚举是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。举例:一周只有7天,一年只有12个月等
格式:public enum 枚举名称 {}
13.1.2、自定义枚举类
13.1.2.1、第一版
public class Direction1 {
// 创建几个实例
public static final Direction1 FRONT = new Direction1();
public static final Direction1 BEHIND = new Direction1();
public static final Direction1 LEFT = new Direction1();
public static final Direction1 RIGHT = new Direction1();
// 私有构造方法
private Direction1() {}
}
13.1.2.2、第二版
public class Direction2 {
// 创建几个实例
public static final Direction2 FRONT = new Direction2("前");
public static final Direction2 BEHIND = new Direction2("后");
public static final Direction2 LEFT = new Direction2("左");
public static final Direction2 RIGHT = new Direction2("右");
// 私有构造方法
private Direction2(String name) {
this.name = name;
}
// 加入成员变量
private String name;
public String getName() {
return name;
}
}
13.1.2.3、第三版
public abstract class Direction3 {
// 创建几个实例
public static final Direction3 FRONT = new Direction3("前") {
@Override
public void show() {
System.out.println("前");
}
};
public static final Direction3 BEHIND = new Direction3("后") {
@Override
public void show() {
System.out.println("后");
}
};
public static final Direction3 LEFT = new Direction3("左") {
@Override
public void show() {
System.out.println("左");
}
};
public static final Direction3 RIGHT = new Direction3("右") {
@Override
public void show() {
System.out.println("右");
}
};
// 加入成员变量
private String name;
// 私有构造方法
private Direction3(String name) {
this.name = name;
}
public String getName() {
return name;
}
// 加入抽象方法
public abstract void show();
}
13.1.2.4、测试方法
public class DirectionDemo {
public static void main(String[] args) {
Direction1 d1 = Direction1.FRONT;
System.out.println(d1);
System.out.println("----------");
Direction2 d2 = Direction2.FRONT;
System.out.println(d2);
System.out.println(d2.getName());
System.out.println("----------");
Direction3 d3 = Direction3.FRONT;
System.out.println(d3);
System.out.println(d3.getName());
d3.show();
}
}
13.1.3、系统的枚举类
13.1.3.1、第一版
public enum Direction1 {
FRONT, BEHIND, LEFT, RIGHT;
}
13.1.3.2、第二版
public enum Direction2 {
FRONT("前"), BEHIND("后"), LEFT("左"), RIGHT("右");
// 添加成员变量
private String name;
// 私有构造方法
private Direction2(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
13.1.3.3、第三版
public enum Direction3 {
FRONT("前") {
@Override
public void show() {
System.out.println("前");
}
},
BEHIND("后") {
@Override
public void show() {
System.out.println("后");
}
},
LEFT("左") {
@Override
public void show() {
System.out.println("左");
}
},
RIGHT("右") {
@Override
public void show() {
System.out.println("右");
}
};
// 添加成员变量
private String name;
// 私有构造方法
private Direction3(String name) {
this.name = name;
}
public String getName() {
return name;
}
// 添加抽象方法
public abstract void show();
}
13.1.3.4、测试方法
public class DirectionDemo {
public static void main(String[] args) {
Direction1 d1 = Direction1.FRONT;
System.out.println(d1);
System.out.println("-------------");
Direction2 d2 = Direction2.FRONT;
System.out.println(d2);
System.out.println(d2.getName());
System.out.println("-------------");
Direction3 d3 = Direction3.FRONT;
System.out.println(d3);
System.out.println(d3.getName());
d3.show();
System.out.println("--------------");
Direction3 dd = Direction3.FRONT;
switch (dd) {
case FRONT:
System.out.println("你选择了前");
break;
case BEHIND:
System.out.println("你选择了后");
break;
case LEFT:
System.out.println("你选择了左");
break;
case RIGHT:
System.out.println("你选择了右");
break;
}
}
}
13.1.4、常见方法
public class EnumMethodDemo {
public static void main(String[] args) {
// int compareTo(E o)
Direction2 d21 = Direction2.FRONT;
Direction2 d22 = Direction2.BEHIND;
Direction2 d23 = Direction2.LEFT;
Direction2 d24 = Direction2.RIGHT;
System.out.println(d21.compareTo(d24));
System.out.println(d22.compareTo(d23));
System.out.println(d23.compareTo(d22));
System.out.println(d24.compareTo(d21));
System.out.println("---------------");
// String name()
System.out.println(d21.name());
System.out.println(d22.name());
System.out.println(d23.name());
System.out.println(d24.name());
System.out.println("--------------");
// int ordinal()
System.out.println(d21.ordinal());
System.out.println(d22.ordinal());
System.out.println(d23.ordinal());
System.out.println(d24.ordinal());
System.out.println("--------------");
// String toString()
System.out.println(d21.toString());
System.out.println(d22.toString());
System.out.println(d23.toString());
System.out.println(d24.toString());
System.out.println("--------------");
// <T> T valueOf(Class<T> type,String name)
Direction2 d = Enum.valueOf(Direction2.class, "FRONT");
System.out.println(d.getName());
System.out.println("----------------");
// values()
Direction2[] directions = Direction2.values();
for (Direction2 direction : directions) {
System.out.println(direction + ":" + direction.getName());
}
}
}
13.1.5、注意事项
- 定义枚举类要用关键字enum
- 所有枚举类都是Enum的子类
- 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其它的东西,这个分号就不能省略,建议不要省略
- 枚举类可以有构造器,但必须是private的,它默认的也是private的。枚举项的用法比较特殊:枚举(“”);
- 枚举类也可以有抽象方法,但是枚举项必须重写该方法
- 枚举在switch语句中的使用
13.2、注解
13.2.1、概述
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。Java 语言中的类、方法、变量、参数和包等都可以被注解。和 Javadoc 不同,Java 注解可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java 虚拟机可以保留注解内容,在运行时可以获取到注解内容 。 当然它也支持自定义 Java 注解。
格式:public @interface 注解名称 {}
13.2.2、元注解
13.2.2.1、@interface注解
使用 @interface 定义注解时,意味着它实现了 java.lang.annotation.Annotation 接口,即该注解就是一个Annotation,定义 Annotation 时,@interface 是必须的,通过 @interface 定义注解后,该注解不能继承其它的注解或接口
13.2.2.2、@Inherited注解
表示允许子类继承父类中的注解
13.2.2.3、@Document注解
表示将此注解包含在 javadoc 中
13.2.2.4、@Target注解
表示该注解目标
- ElemenetType.CONSTRUCTOR 构造器声明
- ElemenetType.FIELD 域声明
- ElemenetType.LOCAL_VARIABLE 局部变量声明
- ElemenetType.METHOD 方法声明
- ElemenetType.PACKAGE 包声明
- ElemenetType.PARAMETER 参数声明
- ElemenetType.TYPE 类、接口、枚举、注解声明
13.2.2.5、@Retention注解
表示该注解的生命周期
- RetentionPolicy.SOURCE 源码期间有效
- RetentionPolicy.CLASS 编译期间有效
- RetentionPolicy.RUNTIME 运行期间有效
13.2.3、参数成员
- 参数成员只能用public或默认(default)这两个访问权修饰
- 参数成员只能用八种基本数据类型(byte,short,int,long,float,double,char,boolean)和String、Enum、Class、Annotations等类型以及这些类型的一维数组
13.2.4、常见注解
@Inherited 只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。
@Documented 所标注内容,可以出现在javadoc中。
@Target 只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。
@Retention 只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。
@Deprecated 所标注内容,不再被建议使用。
@Override 只能标注方法,表示该方法覆盖父类中的方法。
@SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
@FunctionalInterface 所标注接口代表是一个函数式接口。
13.2.5、综合案例
第一步:创建自定义注解,MyTest.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyTest {
public long timeout() default -1;
}
第二步:创建待测试模块,UserDao.java
public class UserDao {
static {
System.out.println("静态代码块执行了");
}
@MyTest
public void addUser() {
System.out.println("增加用户");
}
@MyTest
public void delUser() {
System.out.println("删除用户");
}
@MyTest
public void uptUser() {
System.out.println("更新用户");
}
@MyTest
public void getUser() {
System.out.println("获取用户");
}
}
第三步:反射执行方法,MyJunit.java
import java.lang.reflect.Method;
public class MyJunit {
public static void main(String[] args) throws Exception {
// 获取字节码文件
Class<UserDao> clazz = UserDao.class;
// 获取所有的方法
Method[] mds = clazz.getMethods();
// 遍历所有的方法
for (Method md : mds) {
if (md.isAnnotationPresent(MyTest.class)) {
md.invoke(new UserDao());
}
}
}
}