一、枚举类
1.枚举类的使用
- 类的对象只有有限个,确定的。举例如下:
- 星期:Monday、...、Sunday
- 性别:Man、Woman
- 季节:Spring...Winter
- 支付方式:Cash、WechatPay、AliPay、BankCard、CreditCard
- 就职状态:Busy、Free、Vocation、Dimission
- 订单状态:Nonpayment(未支付)、Payid(已支付)、Fulfilled(已配货)、Delivered(已发货)、Return(退货)、Checked(已确认)
- 线程状态:创建、就绪、运行、阻塞、死亡
- 当需要定义一组常量时,强烈建议使用枚举类。
- 如果枚举类中只有一个对象,则可以作为单例模式的实现方式。
2.如何自定义枚举类
方式一:jdk5.0之前,自定义枚举类
步骤
- 声明类对象属性,为final常量。
- 私有化构造器,并给对象属性赋值。
- 提供当前枚举类的多个对象,public static final。
- 提供获取对象属性的方法、toString方法。
季节类:
//自定义枚举类
class Season {
//1.声明Seanson对象的属性
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 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.其他诉求1:获取枚举类对象的属性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//4.其他诉求2:提供toString方法
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
效果测试:
public class SeasonTest {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring.getSeasonName() + ":" + spring.getSeasonDesc());
}
}
方式二:jdk5.0,使用enum关键字定义枚举类
步骤
-
提供当前枚举类的对象,多个对象之间用","分开,末尾对象";"结束。 -
声明类对象属性,为final常量。 -
提供当前枚举类的多个对象,public static final。 -
提供获取对象属性的方法。
同样以季节类为例:
//使用enum关键字定义枚举类
enum Season1 {
//1.提供当前枚举类的对象,多个对象之间用","分开,末尾对象";"结束
SPRING("春天", "春暖花开"),
SUMMER("夏天", "夏日炎炎"),
AUTUMN("秋天", "秋高气爽"),
WINTER("冬天", "寒冬腊月");
//2.声明Seanson对象的属性
private final String seasonName;
private final String seasonDesc;
//3.私有化构造器,并给对象属性赋值
private Season1(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//4.其他诉求1:获取枚举类对象的属性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
}
效果测试:
public class SeasonTest1 {
public static void main(String[] args) {
Season1 sumber = Season1.SUMMER;
System.out.println(sumber);
//SUMMER
System.out.println(Season1.class.getSuperclass());
//class java.lang.Enum
}
}
可以发现,enum修饰的类,不是Object类,而是继承于Enum类。
?3.Enum类中的常用方法
- values():返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。
- valueof(String objName):返回枚举类中对象名是objName的对象;若没有,则抛异常:IllegalArgumentException
- toString():返回当前枚举类对象常量的名称。
public class SeasonTest1 {
public static void main(String[] args) {
Season1 sumber = Season1.SUMMER;
//toString():
System.out.println(sumber);//SUMMER
//values():
Season1[] values=Season1.values();
for (int i = 0; i < values.length; i++) {
System.out.println(values[i]);
}
//SPRING
//SUMMER
//AUTUMN
//WINTER
//valueof(String objName):返回枚举类中对象名是objName的对象;若没有,则抛异常:IllegalArgumentException
Season1 winter = Season1.valueOf("WINTER");
System.out.println(winter);
//WINTER
}
}
?4.使用enum关键字定义的枚举类实现接口的情况
情况一:实现接口,在enum类中实现抽象方法。
情况二:让枚举类的对象分别实现接口中的抽象方法。
示例:
接口代码
interface show{
void show();
}
enum类代码
enum Season1 implements show{
SPRING("春天", "春暖花开"){
@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("大约在冬季");
}
};
?
二、注解(Annotation)
1.注解概述
? ? ? ? 其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
? ? ? ? Annotation可以像修饰符意义被使用,可用于修饰包,类,构造器,方法,成员遍历,参数,局部变量的声明,这些信息被保存在Annotation的“name=value”对中。
? ? ? ? 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。
? ? ? ? 但未来的开发模式都是基于注解的,JPA、Spring2.5、Hibernate3.x、Struts2基于注解。注解是一种趋势,一定程度上可以说:框架=注解+反射+设计模式。
2.常见的注解示例
- 示例一:生成文档相关的注解
- @author 标明开发该类模块的作者
- @version 标明该类模块的版本
- @see 参考转向,也就是相关主题
- @since 从哪个版本开始增加的
- ......
- 示例二:编译时进行格式检查的内置的三个基本注解
- @Override 限定重写父类方法
- @Deprecated 表示所修饰的元素已过时
- @SuppressWarnings 抑制编译器警告?
- 示例三:跟踪代码依赖性,实现代替配置文件功能
- Servlet3.0提供了注解,使不再需要在web.xml文件中进行Servlet的部署。
- spring框架中关于“事务”的管理。
3.自定义注解
- 定义新的Annotation类型使用@interface关键字。
- 自定义注解自动继承了java.lang.annotation.Annotation接口。
- Annotation的成员变量在Annotation定义中以无参数方法的形式来声明。方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能使8中基本数据类型、String、Class、enum、Annotation、以上所有类型的数组。
- 可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可以使用default关键字。
- 如果只有一个参数成员,建议使用参数名为value。
- 没有成员定义的Annotation称为标记,包含成员变量的Annotation称为元数据Annotation。
注意:自定义注解必须配上注解的信息处理流程(使用反射)才有意义。
注解代码:
public @interface MyAnnotation {
String value() default "hello";
}
使用:
@MyAnnotation(value = "hi")
class Persion {
private String name;
private int age;
public Persion() {
}
public Persion(String name, int age) {
this.name = name;
this.age = age;
}
}
?
4.JDK中的元注解
- 元Annotation用于修饰其他Annotation定义。
- JDK5提供了4个标准的meta-annotation类型:
@Retention
? ? ? ? 只能用于修饰一个Annotation定义,用于指定该Annotation的生命周期,包含一个RetentionPolicy类型的成员变量。
- RetentionPolicy.SOURCE:在源文件中有效,编译器直接丢弃这种策略的注释。
- RetentionPolicy.CLASS:在class文件中有效,当运行Java程序时,JVM不会保留注释。为默认值。
- RetentionPolicy.RUNTIME:在运行时有效,当运行Java程序时,JVM会保留注释。程序可以通过反射获取该注释。
@Target
????????用于指定该Annotation 能用于修饰那些程序元素。
@Documented
????????用于指定该Annotation 将被javadoc工具提取成文档。
@Inherited
? ? ? ? 用于指定该Annotation将具有继承性。如果某个类使用了被@Inherited修饰的Annotation,则其子类自动具有该注解。
5.利用反射获取注解信息
见反射部分。
6.JDK8中注解新特性
1.可重复注解
- 在MyAnnotation上声明@Repetable,成员值为MyAnnotation.class
- MyAnnotation的Target和Retention和MyAnnotations相同。
MyAnnotation:
@Repeatable(MyAnnotations.class)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotation {
String value() default "hello";
}
MyAnnotations:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotations {
MyAnnotation[] value();
}
?MyAnnotation就可以重复注解:
@MyAnnotation(value = "hi")
@MyAnnotation(value = "abc")
class Persion {
private String name;
private int age;
}
2.类型注解
- ElementType.TYPE_PARAMETER :表示该注解能写在类型变量的声明语句中(如泛型声明)
- ElementType.TYPE_USE? :表示该注解能写在使用类型的任何语句中。
|