枚举类注解
一、枚举类:
1.枚举类的使用
类的对象只有有限个,确定的。比如:星期、性别、季节
当需要定义一组常量时,强烈建议使用枚举类。
定义枚举类的方法:
一:jdk5.0之前,自定义枚举类
package com.ypl.meiju;/* 一、枚举类的使用* 1.枚举类的理解:类的对象只有有限个,确定的,我们称此类为枚举类* 2.当需要定义一组常量时,强烈建议使用枚举类* 3.如果枚举类中只有一个对象,则可以作为单例模式的实现方式* 二、如何定义枚举类* 方式一:jdk5.0之前,自定义枚举类* 方式二:jdk5.0,可以使用enum关键字定义枚举类*/ public class SeasonTest {public static void main(String[] args) {Season spring = Season.AUTUMN;System.out.println(spring);}} //自定义枚举类 class Season{//1.声明Season对象的属性:private final修饰private final String seasonName;private final String seasonDesc;//2.私有化类的构造器,并给对象属性赋值private Season(String seasonName,String seasonDesc){this.seasonName=seasonName;this.seasonDesc=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.其他诉求:获取枚举类对象的属性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}//5.其他诉求二:提供toString()@Overridepublic String toString() {return "Season{" +"seasonName='" + seasonName + '\\'' +", seasonDesc='" + seasonDesc + '\\'' +'}';} }
运行之后如下所示:
二:使用enum关键字定义枚举类
package com.ypl.meiju;/* 使用enum关键字定义枚举类* 说明:定义的枚举类默认继承于java.lang.Enum类*/ public class SeasonTest1 {public static void main(String[] args) {Season1 summer = Season1.SUMMER;System.out.println(summer);System.out.println(Season1.class.getSuperclass());} } //使用enum关键字定义枚举类 enum Season1{//1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束SPRING("春天","春暖花开"),SUMMER("夏天","夏日炎炎"),AUTUMN("秋天","秋高气爽"),WINTER("冬天","冰天雪地");//2.声明Season对象的属性:private final修饰private final String seasonName;private final String seasonDesc;//2.私有化类的构造器,并给对象属性赋值private Season1(String seasonName,String seasonDesc){this.seasonName=seasonName;this.seasonDesc=seasonDesc;}//4.其他诉求:获取枚举类对象的属性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}//5.其他诉求二:提供toString() //可以进行重写,也可以不进行重写。/* @Overridepublic String toString() {return "Season1{" +"seasonName='" + seasonName + '\\'' +", seasonDesc='" + seasonDesc + '\\'' +'}';}*/ }
运行之后如下所示:
三、Enum类中的常用方法:
values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值
valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常
toString():返回当前枚举类对象常量的名称
package com.ypl.meiju;/* 使用enum关键字定义枚举类* 说明:定义的枚举类默认继承于java.lang.Enum类 三、Enum类中的常用方法*values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值*valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常*toString():返回当前枚举类对象常量的名称*我们之前在学习多线程的时候,Thread.State:*源码如下所示:*public enum State {*四、使用enum关键字定义的枚举类实现接口的情况* 情况一:实现接口,在enum类中实现抽象方法* 情况二:让枚举类的对象分别实现接口中的抽象方法*/public class SeasonTest1 {public static void main(String[] args) {Season1 summer = Season1.SUMMER;System.out.println(summer);System.out.println(Season1.class.getSuperclass());System.out.println("toString方法如下所示:");//toString()方法System.out.println(summer.toString());//values()方法System.out.println("*");Season1[] values = Season1.values();for (int i=0;i< values.length;i++){System.out.println(values[i]);}System.out.println("$$$$$$$$$$$$$$$$$");for (int i=0;i< values.length;i++){System.out.println(values[i]);values[i].show();}System.out.println("$$$$$$$$$$$$");System.out.println("Thread类的循环");//Thread.stateThread.State[] values1 = Thread.State.values();for (int i=0;i<values1.length;i++){System.out.println(values1[i]);}System.out.println("*");//如果没有objNname的枚举类对象,则抛异常:IllegalArgumentException// valueOf(String objName):根据提供的objName,返回枚举类中对象名是objName的对象。Season1 winter = Season1.valueOf("WINTER");System.out.println(winter);winter.show();} }interface Info{void show();}//使用enum关键字定义枚举类 enum Season1 implements Info{//1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束SPRING("春天","春暖花开"){@Overridepublic void show() {System.out.println("春天在哪里");}},SUMMER("夏天","夏日炎炎"){@Overridepublic void show() {System.out.println("宁静的夏天");}},AUTUMN("秋天","秋高气爽"){@Overridepublic void show() {System.out.println("秋天不回来");}},WINTER("冬天","冰天雪地"){@Overridepublic void show() {System.out.println("大约在冬季");}};//2.声明Season对象的属性:private final修饰private final String seasonName;private final String seasonDesc;//2.私有化类的构造器,并给对象属性赋值private Season1(String seasonName,String seasonDesc){this.seasonName=seasonName;this.seasonDesc=seasonDesc;}//4.其他诉求:获取枚举类对象的属性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}//5.其他诉求二:提供toString() //可以进行重写,也可以不进行重写。/* @Overridepublic String toString() {return "Season1{" +"seasonName='" + seasonName + '\\'' +", seasonDesc='" + seasonDesc + '\\'' +'}';}*//*@Overridepublic void show() {System.out.println("这是一个季节");}*/ }
运行之后如下所示:
二、注解
从JDK5.0开始,Java增加了人对元数据的支持,也就是Annotation(注解)
Annotation其实就是代码里的特殊标记,这些标记可以在编译,类加载。运行时被读取,并执行相应的处理。通过使用Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息,代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署
Annotation可以像修饰符一样被使用,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存在Annotation的“name=value"对中。
框架=注解+反射+设计模式
使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素
示例一:生成文档相关的注解
示例二:在编译时进行格式检查(JDK内置的三个基本注解)
@Override:限定重写父类方法,该注解只能用于方法
@Deprecated:用于表示所修饰的元素(类,方法等)已过时,通常是因为所修饰的结构危险或存在更好的选择。
@SuppressWarnings:抑制编译器警告
示例三:跟踪代码依赖性,实现替代配置文件功能
package com.ypl.zhujie;import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Date;/* 注解的使用* 1.理解Annotation:* (1)jdk5.0新增的功能* (2)Annotation其实就是代码里的特殊标记,这些标记可以在编译* ,类加载。运行时被读取,并执行相应的处理。通过使用Annotation,程* 序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。* 2.Annotation的使用示例:* 示例一:生成文档相关的注解* 示例二:在编译时进行格式检查(JDK内置的三个基本注解)* @Override:限定重写父类方法,该注解只能用于方法* @Deprecated:用于表示所修饰的元素(类,方法等)已过时,通常是因为所修饰的结构危险或存在更好的选择。* 我们的类里面体现出如下所示:* @Deprecated* public Date(int year, int month, int date) {* this(year, month, date, 0, 0, 0);* }* v:抑制编译器警告* 示例三:跟踪代码依赖性,实现替代配置文件功能* 3.如何自定义注解:参照@SuppressWarnings定义* public @interface SuppressWarnings* (1)注解声明为:@interface* (2)内部定义成员,通常使用value表示* (3)可以指定成员的默认值,使用default定义* (4)如果自定义注解没有成员,表明是一个标识作用。 如果注解有成员,在使用注解时,需要指明成员的值* 自定义注解必须配上注解的信息处理流程(使用反射)才有意义。* 4.jdk提供的4种元注解* JDK的元Annotation用于修饰其他Annotation定义* 元数据:对现有数据的修饰* 元注解:修饰其他注解的注解(对现有的注解进行解释说明的注解、* 元注解示例如下所示:* @Target(ElementType.METHOD)* @Retention(RetentionPolicy.SOURCE)* public @interface Override {* } 自定义注解通常都会指明两个元注解:Retention、Target* 4.JDK5.0提供了4个标准的meta-annotation类型,分别是:* Retention:指定所修饰的Annotation的生命周期:SOURCE\\CLASS(默认行为)\\RUNTIME* 只有声明为RUNTIME生命周期的注解,才能通过反射获取。* Target:用于指定被修饰的Annotation能用于修饰哪些程序元素* *出现的频率较低 Documented:表示所修饰的注解在被javaDoc解析时,保留下来。* Inherited:被它修饰的Annotation将具有继承性。* 5.通过反射来获取注解信息* 6.jdk 8中注解的新特性:可重复注解、类型注解* 6.1可重复注解:(1)在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class* (2)MyAnnotation的Target和Retention等元注解与MyAnnotations相同。* 6.2类型注解:* public enum ElementType {* TYPE_PARAMETER,* TYPE_USE* ElementType.TYPE_PARAMETER表示该注解能写在类型变量的声明语句中(泛型声明)* ElementType.TYPE_USE表示该注解能写在使用类型的任何语句中/public class AnnotationTest {public static void main(String[] args) {@SuppressWarnings("unused")int num=10; //未调用的时候颜色为灰色,添加此注释即可进行抑制Class studentClass = Student.class;Annotation[] annotations = studentClass.getAnnotations();for (int i=0;i<annotations.length;i++){System.out.println(annotations[i]);}}}//jdk 8之前的写法: //@MyAnnotations({@MyAnnotation(value ="hi"),@MyAnnotation(value ="hi")} ) //JDK1.8后的写法: @MyAnnotation(value ="hi") @MyAnnotation(value ="abc") class Person{private String name;private int age;@MyAnnotationpublic Person(String name, int age) {this.name = name;this.age = age;}public Person() {}public void walk(){System.out.println("人走路");}public void eat(){System.out.println("人吃饭");}}interface Info{void show(); }class Student extends Person implements Info{@Overridepublic void walk() {System.out.println("学生走路");}@Overridepublic void show() {} }class Generic<@MyAnnotation T>{public void show() throws @MyAnnotation RuntimeException{ArrayList<@MyAnnotation String> list=new ArrayList<>();int num=(@MyAnnotation int)10L;} }
我们的自定义注解如下所示:
package com.ypl.zhujie;import java.lang.annotation.*;import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.LOCAL_VARIABLE;@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Repeatable(MyAnnotations.class) public @interface MyAnnotation {String value() default "hello"; }
package com.ypl.zhujie;import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.LOCAL_VARIABLE;@Inherited @Retention(RetentionPolicy.RUNTIME) @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) public @interface MyAnnotations {MyAnnotation [] value(); }