第十三章 枚举类和注解


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、注意事项

  1. 定义枚举类要用关键字enum
  2. 所有枚举类都是Enum的子类
  3. 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其它的东西,这个分号就不能省略,建议不要省略
  4. 枚举类可以有构造器,但必须是private的,它默认的也是private的。枚举项的用法比较特殊:枚举(“”);
  5. 枚举类也可以有抽象方法,但是枚举项必须重写该方法
  6. 枚举在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、参数成员

  1. 参数成员只能用public或默认(default)这两个访问权修饰
  2. 参数成员只能用八种基本数据类型(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());
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38490457/article/details/107495440