Java基础汇总(八)——枚举、注解

一、枚举

1.定义

        枚举类型是某类数据可能取值的集合

        如一周内星期可能取值的集合为:{Sun,Mon,Tue,Wed,Thu,Fri,Sat} ,该集合可定义为描述星期的枚举类型,该枚举类型共有七个元素,因而用枚举类型定义的枚举变量只能取集合中的某一元素值。

        枚举类型为导出数据类型,所以要先定义枚举类型,再用枚举类型定义枚举型变量

enum <枚举类型名> 
  { <枚举元素表> };
  其中:关键词enum表示定义的是枚举类型,枚举类型名由标识符组成,而枚举元素表由枚举元素或枚举常量组成

例1:

enum weekdays 
  { Sun,Mon,Tue,Wed,Thu,Fri,Sat };

        在编译器编译程序时,可给枚举类型中的指定个元素指定一个整型常量值(序号值)。若枚举类型定义中没有指定元素的整型常量值,则整型常量值从0开始依次递增。

例2:

描述逻辑值集合{TRUE、FALSE}的枚举类型boolean可定义如下:
enum boolean 
  { TRUE=1 ,FALSE=0 };
该定义规定:TRUE的值为1,而FALSE的值为0。
  
描述颜色集合{red,blue,green,black,white,yellow}的枚举类型colors可定义如下:
enum colors 
  {red=5,blue=1,green,black,white,yellow};
  该定义规定red为5 ,blue为1,其后元素值从2 开始递增加1。green、black、white、yellow的值依次为2、3、4、5。

        两个不同元素取相同的整数值是没有意义的,如red和yellow都是5

        枚举类型的定义只是定义了一个新的数据类型,只有用枚举类型定义枚举变量才能使用这种数据类型

2.枚举类的注意事项

  • 默认继承 java.lang.Enum 类,不能继承其他父类
  •  java.lang.Enum 类实现了 java.lang.Serializable 和 java.lang.Comparable 接口
  • enum默认使用 final 修饰,不能派生子类
  • 构造器默认使用 private 修饰,且只能使用 private 修饰
  • 枚举类所有实例必须在第一行给出,默认添加 public static final 修饰,否则无法产生实例

3.枚举类使用

参考链接:

Java 枚举(enum) 详解7种常见的用法_请叫我大师兄_的博客-CSDN博客_枚举类型enum用法

4.枚举类集合:

  • java.util.EnumSet:保证集合中的元素不重复
  • java.util.EnumMap:EnumMap中的 key是enum类型,而value则可以是任意类型

例3:

import java.util.*;
 
enum Season
{
	SPRING,SUMMER,FALL,WINTER
}
public class EnumMapTest
{
	public static void main(String[] args)
	{
		// 创建EnumMap对象,该EnumMap的所有key都是Season枚举类的枚举值
		EnumMap enumMap = new EnumMap(Season.class);
		enumMap.put(Season.SUMMER , "小荷才露尖尖角");
		enumMap.put(Season.SPRING , "满园春色关不住");
		System.out.println(enumMap);
	}
}

//SPRING=满园春色关不住, SUMMER=小荷才露尖尖角


枚举成员名称需要全部大写,单词间用下划线隔开

enum Season
{
    SPRING,SUMMER,FALL,WINTER
}

        枚举类型对象之间的值比较可以使用“==”直接来比较值是否相等的,不是必须使用equals方法,因为枚举类Enum已经重写了equals方法

        每个枚举都定义了两个属性,name和ordinal,name表示我们定义的枚举常量的名称,如FRIDAY、TUESDAY,而ordinal是一个顺序号,根据定义的顺序分别赋予一个整形值,从0开始。在枚举常量初始化时,会自动为初始化这两个字段,设置相应的值,在构造方法中添加了两个参数。

        name和ordinal属性都是final的,clone、readObject、writeObject这三个方法也是final的,这三个方法和枚举通过静态代码块来一起进行初始化。

        clone、readObject、writeObject三个方法保证了枚举类型的不可变性(即不能通过克隆,不能通过序列化和反序列化来复制枚举),保证枚举常量是单例的。

5.枚举类总结

  • 每个枚举类型都继承自java.lang.Enum,并自动添加了values(获取枚举类中的所有枚举值)和valueOf(获取对应的枚举类型)方法
  • 每个枚举常量是一个静态常量字段,使用内部类实现,该内部类继承了枚举类。所有枚举常量都通过静态代码块来进行初始化,即在类加载期间就初始化。
  • 通过把clone、readObject、writeObject这三个方法定义为final的,同时实现是抛出相应的异常。这样保证了每个枚举类型及枚举常量都是不可变的。可以利用枚举的这两个特性来实现线程安全的单例

二、注解

1.定义

        它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用

  • 注解是绑定到程序源代码元素的元数据,对运行代码的操作没有影响

2.元注解

定义:

        适用于其他注解的注解,所有未使用@Target标记或使用它标记但包含ANNOTATION_TYPE常量的注解也是元注解

例:

@Target(ElementType.ANNOTATION_TYPE)
public @interface SimpleAnnotation {
    // ...
}

@Retention– 定义该注解的生命周期

  • RetentionPolicy.SOURCE:在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解
  • RetentionPolicy.CLASS:在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
  • RetentionPolicy.RUNTIME:始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式

@Target –注解用于什么地方

  • ElementType.CONSTRUCTOR:用于描述构造器
  • ElementType.FIELD:成员变量、对象、属性(包括enum实例)
  • ElementType.LOCAL_VARIABLE:用于描述局部变量
  • ElementType.METHOD:用于描述方法
  • ElementType.PACKAGE:用于描述包
  • ElementType.PARAMETER:用于描述参数
  • ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Documented –注解是否将包含在JavaDoc中

@Inherited – 是否允许子类继承该注解(使用@Inherited修饰的注解可以被子类继承)

  • 如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类

3.注解的典型用例

  • 编译器的信息 - 使用注解,编译器可以检测错误或抑制警告

  • 编译时和部署时处理 - 软件工具可以处理注解并生成代码,配置文件等。
  • 运行时处理 - 可以在运行时检查注解以自定义程序的行为

4.常用注解(部分)

  • @Override -标记方法是否覆盖超类中声明的元素。如果它无法正确覆盖该方法,编译器将发出错误
  • @Deprecated - 表示该元素已弃用且不应使用。如果程序使用标有此批注的方法,类或字段,编译器将发出警告
  • @SuppressWarnings - 告诉编译器禁止特定警告。在与泛型出现之前编写的遗留代码接口时最常用的
  • @FunctionalInterface - 在Java 8中引入,表明类型声明是一个功能接口,可以使用Lambda Expression提供其实现
  • 注解方法声明返回类型必须是基本类型,String,Class,Enum或数组类型之一。否则,编译器将抛出错误
  • @Target注解可以限制应用注解的元素

                如果我们尝试在不适用的上下文中使用注解,编译器将发出错误

                如果我们想让它适用于更多的上下文,我们可以传递多个常量

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE })

如果在@Target注解中多次出现相同的枚举常量,那么这是一个编译时错误

例:

@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.FIELD })
public @interface TestAnnotation {
    int[] value() default {};
}

参考文章:

Java-Tutorial/15、Java注解和最佳实践.md at master · h2pl/Java-Tutorial · GitHub

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值