enum 和注解
枚举:
类的对象只有有限个确定的时候就可以使用枚举 我们知道有多少个对象 就可以使用枚举
eg : 一周的天数, 季节, 订单状态 ,性别之类的
当需要定义一组常量时候 强烈建议使用枚举
枚举的使用:
jdk1.5之间使用自定义枚举类
jdk1.5之后新增enum关键字用于定义枚举类
枚举类的理解
1: 枚举类的理解:类的对象只有有限个,确定的 我们称为枚举类 也就是这个类是已知的 2: 当需要定义一组常量时,我们强烈建议使用枚举类 3: 如果枚举类中只有一个对象 则可以作为单例模式的实现方式
自定义枚举类:
public class SeasonTest { public static void main(String[] args) { System.out.println(SeasonTT.SPRING.getClass().getSuperclass()); System.out.println(SeasonTT.SPRING); } } class SeasonTT{ // 1 声明Season对象的属性:Private final属性 private final String name; private final String SeasonDesc; // 2 : 私有化类的构造器 private SeasonTT(String name, String SeasonDesc){ this.name = name; this.SeasonDesc = SeasonDesc; } // 提供当前枚举类的多个对象 public static final SeasonTT SPRING = new SeasonTT("春天","春风拂面"); public static final SeasonTT SUMMER = new SeasonTT("夏天", "夏日炎炎"); public static final SeasonTT AUTUMN = new SeasonTT("秋天","秋高气爽"); public static final SeasonTT WINTER = new SeasonTT("冬天","白雪皑皑"); @Override public String toString() { return "SeasonTT{" + "name='" + name + '\'' + ", SeasonDesc='" + SeasonDesc + '\'' + '}'; } }
enum关键字实现枚举类
public class SeasonTestT { public static void main(String[] args) { // values() 获取枚举类的所有对象 Sea [] seas = Sea.values(); for (int i = 0; i <seas.length ; i++) { System.out.println(seas[i]); } // valueOf(enumObject, obj) 获取枚举类的其中obj对象的内容 System.out.println(Sea.valueOf("SPRING")); // toString() 获取其对象内容 } } enum Sea{ // 实现对象必须放置在这个枚举类的第一部分 不然会报错 //提供当前枚举类的对象 多个对象之间用逗号隔开 SPRING ("老王",14), SUMMER("老李",16), AUTUMN("老张",19), WINTER("老洪",25); private final String name; private final int age; private Sea(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Sea{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
.
/* enum 枚举的方法 value() :返回枚举类型的对象数组, 该方法可以很方便地遍历所有枚举值 valueOf(String str) : 可以把一个字符串转为对应的枚举对象,要求字符串必须是枚举对象 toString() 输出默认枚举类的名称 */ import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput; public class SeasonTestOne { public static void main(String[] args) { System.out.println(SeasonT.valueOf("Sprint")); // SeasonT{name='春天', seasonDesc='春风拂面'} SeasonT[] seasonTS = SeasonT.values(); for (int i = 0; i < seasonTS.length; i++) { System.out.println(seasonTS[i]); // 获取所有枚举对象的值 } SeasonT summer = SeasonT.valueOf("SUMMER"); summer.show(); } } interface Info{ void show(); } enum SeasonT implements Info{ //提供当前枚举类的对象 多个对象之间用逗号隔开,末尾用; 分号结束 Sprint("春天", "春风拂面"){ //每一个枚举对象调用同一个接口实现的不同的方法输出 @Override public void show(){ System.out.println("这是春天"); } }, SUMMER("夏天", "夏日炎炎"){ @Override public void show(){ System.out.println("这是夏天"); } }, AUTUMN("秋天", "秋高气爽"){ @Override public void show(){ System.out.println("这是秋天"); } }, WINTER("冬天", "白雪皑皑"){ @Override public void show(){ System.out.println("This is winter"); } }; private final String name; private final String seasonDesc; private SeasonT(String name, String seasonDesc) { this.name = name; this.seasonDesc = seasonDesc; } @Override public String toString() { return "SeasonT{" + "name='" + name + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}'; } // public void show(){ // System.out.println("这是一个季节"); // } }
枚举类在实现接口的时候 可普通类一样 当需要枚举对象实现同一个接口的方法 输出不同时可以在生成枚举对象时进行方法不同的重写
interface InfoOne{ void show(); } enum Sea implements InfoOne{ // 实现对象必须放置在这个枚举类的第一部分 不然会报错 //提供当前枚举类的对象 多个对象之间用逗号隔开 SPRING ("老王",14){ //每一个枚举对象调用同一个接口实现的不同的方法输出 @Override public void show(){ System.out.println("我是老王实现接口show方法"); } }, SUMMER("老李",16){ @Override public void show(){ System.out.println("我是老李实现接口show方法"); } }, AUTUMN("老张",19){ @Override public void show(){ System.out.println("我是老张实现接口show方法"); } }, WINTER("老洪",25){ @Override public void show(){ System.out.println("我是老洪实现接口show方法"); } };
注解:Annotation
Annotation也就是代码里的特殊处理。这些标记可以在编译类家载时,运行时被读取, 并执行响应的处理通过使用Annotation程序员可以在不改变原有逻辑的情况下 在源文件中嵌入一些补充信息(类似于python的装饰器)
在不改变原代码的情况下 增加一些其余的操作
常见的注解:
@Override 限定重写的父类方法 该注解只能用于方法
@Deprecated 用于表示所修饰的元素 已经过时, 通过因为修饰的结构不安全或者是有了更好的选择
@ SuppressWarning 抑制编译器警告
自定义注解:
@interface 关键字
自定义注解自动集成了 java.lang.annotation.Annotation 接口
public @interface MyAnnocation { String value(); }
定义的注解其方法名和返回值定义了该成员的名字和类型, 我们称为配置参数,类型只能是8中基本数据类型
String, Class, enum。 Annotation,以上类型的数组
也可以设置默认值,如果没有设置默认值的时候 需要使用方指定值, 默认值直接在参数后default "默认值"
public @interface MyAnnocation { String value() default "hello"; }
@MyAnnocation(value = "hello") class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; }
java的元注解:
是用来修饰注解的
Retention : 声明注解地生命周期
Target : 声明注解地使用范围 是可以对类还是方法使用 能用于修饰那些程序元素,
Target:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
// 限定这个注解可以对那些元素使用 //@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) // 可以对所有ed使用 @Target({TYPE, FIELD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) // 不可以对方法使用 public @interface MyAnnocation { String value(); }
/* 注解 @override :限定重写父类方法 该注解只能用于方法 @Deprecated 用于表示所修饰的元素(类,方法等)已过时 通常是因为所修饰的结构危险或者存在更好的选择 @SuppressWarning 抑制编译器警告 */ import java.util.Date; public class AnnocationTest { public static void main(String[] args) { Date date = new Date(2020,10,11); System.out.println(date); @SuppressWarnings("unused") // 未使用的 int num = 10; } } class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; public void waik(){ System.out.println("人走路"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
练习:
1: 编写一个Person类 使用Override注解它的toString方法 2: 自定义一个名为MyTiger的注解类型 它只可以使用在方法上,带一个String类型的value属性,然后再第一题中的Person类上使用
class PerOne{ private String name; private int age; public PerOne(String name, int age) { this.name = name; this.age = age; } @MyTeger(value = "老王") @Override public String toString() { return "PerOne{" + "name='" + name + '\'' + ", age=" + age + '}'; } } @Target({METHOD}) @interface MyTeger{ String value(); }
.