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等