15.Java枚举类-注解

Java枚举类-注解


一、枚举类

1. 理解

 * 1. 枚举类的理解:类的对象只有有限个,确定的。则此类可以看做是枚举类。
 * 
 * 2. 举例:
 * 星期:Monday(星期一)、......、Sunday(星期天)
 * 性别:Man(男)、Woman(女)
 * 季节:Spring(春节)......Winter(冬天)
 * 支付方式:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)
 * 就职状态:Busy、Free、Vocation、Dimission
 * 订单状态:Nonpayment(未付款)、Paid(已付款)、Delivered(已发货)、Return(退货)、Checked(已确认)Fulfilled(已配货)
 * 线程状态:创建、就绪、运行、阻塞、死亡
 * 
 * 3. 当需要定义一组常量时,强烈建议使用枚举类
 * 4. 如果枚举类的对象只有一个,则枚举类可以看做单例模式的实现方式。

2. 如何自定义枚举类

public class SeasonTest {
	public static void main(String[] args) {
		Season summer = Season.SUMMER;
		System.out.println(summer);
		System.out.println(summer.getSEASON_NAME());
		
	}
}

//自定义枚举类
class Season{
	
	//1. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//2. 私有化类的构造器
	private Season(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	
	//3. 创建枚举类中的对象:public static final 
	public static final Season SPRING = new Season("春天","春暖花开");
	public static final Season SUMMER = new Season("夏天","夏日炎炎");
	public static final Season AUTUMN = new Season("秋天","秋高气爽");
	public static final Season WINTER = new Season("冬天","白雪皑皑");
	
	//4. 提供toString()
	@Override
	public String toString() {
		return "Season [SEASON_NAME=" + SEASON_NAME + ", SEASON_DESC=" + SEASON_DESC + "]";
	}

	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}
	
	
}

3. 使用enum关键字定义枚举类

//使用enum关键字定义枚举类
enum Season1 implements Info{
	//1. 创建枚举类中的对象,声明在enum枚举类的首位
	SPRING("春天","春暖花开"),
	SUMMER("夏天","夏日炎炎"),
	AUTUMN("秋天","秋高气爽"),
	WINTER("冬天","白雪皑皑");
	
	//2. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//3. 私有化类的构造器
	private Season1(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	

	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}


	@Override
	public void show() {
		System.out.println("这是一个美好的季节!");
	}
	
	
}

4. java.lang.Enum类中的常用方法

 * 		toString():返回当前枚举类对象的对象名
 * 		values():返回当前枚举类中所有对象构成的数组
 * 		valueOf(String name):返回指定name名称的枚举类的对象
public class SeasonTest1 {
	public static void main(String[] args) {
		Season1 summer = Season1.SUMMER;
		//toString():返回当前枚举类对象的对象名
		System.out.println(summer.toString());
		
		System.out.println(Season1.class.getSuperclass());//class java.lang.Enum
		
		
		//values():返回当前枚举类中所有对象构成的数组
		Season1[] seasons = Season1.values();
		for(int i = 0;i < seasons.length;i++){
			System.out.println(seasons[i]);
			seasons[i].show();
		}
		
		//valueOf(String name):返回指定name名称的枚举类的对象
		String name = "AUTUMN";
		Season1 s1 = Season1.valueOf(name);
		System.out.println(s1);//AUTUMN
		
		name = "AUTUMN1";
		//如果枚举类中不存在指定名称的枚举类对象,则报java.lang.IllegalArgumentException。
//		Season1 s2 = Season1.valueOf(name);
//		System.out.println(s2);
		
	}
}

5. 枚举类实现接口中的方法

interface Info{
	void show();
}

//使用enum关键字定义枚举类
enum Season1 implements Info{
	//1. 创建枚举类中的对象,声明在enum枚举类的首位
	SPRING("春天","春暖花开"){
		public void show(){
			System.out.println("春天在哪里?");
		}
	},
	SUMMER("夏天","夏日炎炎"){
		public void show(){
			System.out.println("宁静的夏天");
		}
	},
	AUTUMN("秋天","秋高气爽"){
		public void show(){
			System.out.println("秋天是用来分手的季节");
		}
	},
	WINTER("冬天","白雪皑皑"){
		public void show(){
			System.out.println("2002年的第一场雪");
		}
	};
	
	//2. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//3. 私有化类的构造器
	private Season1(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	

	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}

	
}

四、注解(Annotation)

1. 注解的理解

 * 1. Annotation,是jdk5.0新增的特性
 * 2. 理解:
 * Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 
 * 并执行相应的处理。通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件
 * 中嵌入一些补充信息。

2. 注解的应用举例

   示例一:生成文档相关的注解
 * 	@author 标明开发该类模块的作者,多个作者之间使用,分割
 *  @version 标明该类模块的版本
 *  @see 参考转向,也就是相关主题
 *  @since 从哪个版本开始增加的
 * 
 * 示例二:在编译时进行格式检查(JDK内置的三个基本注解)
 * @Override: 限定重写父类方法, 该注解只能用于方法
 * @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
 * @SuppressWarnings: 抑制编译器警告
 * 
 * 示例三:跟踪代码依赖性,实现替代配置文件功能

3. java基础阶段常见的三个注解

 * 	@Override: 限定重写父类方法, 该注解只能用于方法
 *  @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
 *  			 标识为过时的结构,虽然还可以在程序中使用,但是不建议使用。
 *  @SuppressWarnings: 抑制编译器警告
public class AnnotationTest {
	
	public static void main(String[] args) {
		Person p = new Student();
		p.walk();
		
		@SuppressWarnings("deprecation")
		Date date = new Date(2020 - 1900,3 - 1,4);
		System.out.println(date);//Wed Mar 04 00:00:00 GMT+08:00 2020
		
		p.eat();
		
		@SuppressWarnings("unused")
		int num = 10;
//		System.out.println(num);
		
		@SuppressWarnings({ "rawtypes", "unused" })
		List list = new ArrayList();
	}
}


class Person{
	@Deprecated
	public void eat(){
		System.out.println("人吃饭");
	}
	public void walk(){
		System.out.println("人走路");
	}
	
}

class Student extends Person{
	
	@Override
	public void walk() {
		super.walk();
	}
}

4. 如何自定义注解

如何自定义注解(了解)
 * 		参照@SuppressWarnings定义
 * 	   ① 使用@interface来声明
 *     ② 内部可以声明属性,属性类型限于:八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组
 *     ③ 如果注解内部不定义任何属性,则称为标识注解
 *     ④ 属性可以声明默认值,使用default定义
 * 
 *   说明:要想自定义的注解在使用在相关结构的位置上起作用,必须结合后面的反射。通过反射获取相应的注解及注解上的属性的值,进行必要的操作。
 * 
public @interface MyAnnotation {
	String value() default "atguigu";
}

使用自定义的注解:

@MyAnnotation
class Person{
	
	@Deprecated
	public void eat(){
		System.out.println("人吃饭");
	}
	
	@MyAnnotation(value="hello")
	public void walk(){
		System.out.println("人走路");
	}
	
}

5. 元注解

用于修饰现有注解的注解,就称为元注解

  • Retention:用于指定该 Annotation 的生命周期

    • SOURCE:编译不保留 ; CLASS(默认行为):编译保留,运行不保留;RUNTIME:编译保留,运行也保留
  • Target:用于指定被修饰的 Annotation 能用于修饰哪些程序元素。

在这里插入图片描述

  • Documented:用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档

  • Inherited:被它修饰的 Annotation 将具有继承性。

    说明:一般注解都会提供两个元注解: @Retention,@Target。

举例:

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
	String value() default "atguigu";
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

在这里插入图片描述

6. 如何通过反射获取注解的信息(放到反射章节再讲)

​ 前提:要求当前注解的生命周期为:RUNTIME

7. jdk8注解新特性(了解)

  • 重复注解

    import static java.lang.annotation.ElementType.CONSTRUCTOR;
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.PARAMETER;
    import static java.lang.annotation.ElementType.TYPE;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotations {
    	MyAnnotation[] value();
    }
    
    @Repeatable(MyAnnotations.class)
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    	String value() default "atguigu";
    }
    
    
    //旧的写法
    //@MyAnnotations({@MyAnnotation,@MyAnnotation(value="abc")})
    //新的写法
    @MyAnnotation(value="abc")
    @MyAnnotation
    class Person{
    }
    
  • 类型注解

    在Target的属性可以赋值为:

在这里插入图片描述

修改MyAnntation可以修饰的结构:

@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	String value() default "atguigu";
}

测试:

public class AnnotationTest {
	
	public <@MyAnnotation T> void method(T t){
		
		int a  = (@MyAnnotation int)2L;
	}
}

五、小结

  • 枚举类

    • 以后大家在项目中,需要定义一组常量时,建议使用枚举类!
    • 两种定义方式:① 自定义方式 ② 使用enum关键字定义(jdk5.0)
    • 使用enum关键字定义的枚举类默认继承于java.lang.Enum类
      • 常用方法:toString()、values()、valueOf(String name)
    • 枚举类各个对象实现接口中的方法
  • 注解(annotation)

    • JavaSE部分常用的三个注解:@Override @Deprecated @SuppressWarnings
    • 体会:框架 = 注解 + 反射 + 设计模式
    • 元注解:用来修饰现有的注解结构的注解
      • Retention、Target等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值