20.java枚举和注解

枚举

在Java中,枚举(Enumeration)是一种特殊的数据类型,用于定义一组命名的常量。枚举类型在Java中首次引入是在Java 5版本中的,它提供了一种更好的方式来表示一组固定的常量。

以下是关于Java枚举的一些详细信息和示例:

枚举的声明

要声明一个枚举,可以使用enum关键字。枚举类型中的每个常量都是该枚举类型的一个实例。

enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

枚举常量

枚举类型中的常量是预定义的实例。在上面的例子中,Day枚举有七个常量,分别代表一周的每一天。

枚举的使用

public class EnumExample {
    public static void main(String[] args) {
        // 使用枚举常量
        Day today = Day.MONDAY;
        
        // 枚举常量的比较
        if (today == Day.MONDAY) {
            System.out.println("It's Monday!");
        }
        
        // 遍历枚举常量
        for (Day day : Day.values()) {
            System.out.println(day);
        }
    }
}

枚举方法

假设我们要表示一个简单的交通信号灯系统,我们可以使用枚举来定义不同颜色的信号灯状态。以下是一个具体的例子:

// 定义交通信号灯的枚举类型
enum TrafficLightColor {
    RED("Stop"), YELLOW("Prepare to stop"), GREEN("Go");

    private final String description;

    TrafficLightColor(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

// 使用交通信号灯的例子
public class TrafficLightExample {
    public static void main(String[] args) {
        // 获取所有信号灯颜色
        TrafficLightColor[] allColors = TrafficLightColor.values();

        // 遍历并输出每个信号灯的颜色和描述
        for (TrafficLightColor color : allColors) {
            System.out.println("Color: " + color.name());
            System.out.println("Description: " + color.getDescription());
            System.out.println("----");
        }

        // 模拟交通灯变换
        simulateTrafficLight();
    }

    private static void simulateTrafficLight() {
        TrafficLightColor currentColor = TrafficLightColor.RED;

        // 模拟交通灯变换过程
        for (int i = 0; i < 3; i++) {
            System.out.println("Current Color: " + currentColor.name());
            System.out.println("Description: " + currentColor.getDescription());
            System.out.println("----");

            // 切换到下一个颜色
            currentColor = getNextColor(currentColor);

            // 暂停一秒钟,模拟信号灯变换的时间
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static TrafficLightColor getNextColor(TrafficLightColor currentColor) {
        switch (currentColor) {
            case RED:
                return TrafficLightColor.GREEN;
            case YELLOW:
                return TrafficLightColor.RED;
            case GREEN:
                return TrafficLightColor.YELLOW;
            default:
                throw new IllegalArgumentException("Invalid traffic light color");
        }
    }
}

在上面的例子中,我们定义了一个 TrafficLightColor 枚举类型,它包含三个常量:REDYELLOWGREEN,分别代表交通灯的红、黄、绿三种颜色。每个常量都有一个描述属性,并且我们可以通过 getDescription() 方法获取它。

然后,我们在 TrafficLightExample 类中使用了这个枚举类型。我们遍历了所有的信号灯颜色,并输出了它们的颜色和描述。接着,通过 simulateTrafficLight() 方法模拟了交通灯的变换过程,每隔一秒钟切换到下一个颜色,直到循环结束。

这个例子展示了如何定义、使用枚举类型,并通过枚举类型的方法获取相关信息。

注意事项

  1. 枚举类型的常量是静态的,可以通过EnumType.CONSTANT_NAME访问。
  2. 枚举类型可以包含构造方法、普通方法、字段等。
  3. 枚举类型不能继承其他类,但可以实现接口。
  4. 可以在枚举类型中覆盖toString()方法,以自定义枚举常量的字符串表示。

注解

注解(Annotation)是一种元数据的形式,用于在Java代码中提供额外的信息。它们以@符号为前缀,可以标记在类、方法、字段等程序元素上。注解不直接影响程序的运行,而是提供给编译器、工具和框架更多的信息,以实现更灵活的配置和行为。在Java中,有一些内置的注解,例如@Override@Deprecated@SuppressWarnings等,它们用于标记方法重写、过时的代码、抑制警告等情况。程序员还可以自定义注解,使得代码更易读、更易维护。

jdk内置注解

Java提供了一些内置的注解,它们被广泛用于不同的场景,包括编译时检查、运行时处理、文档生成等。以下是一些常见的内置注解:

  1. @Override:

    • 用途: 用于标记一个方法是覆盖父类的方法。
    • 示例:
      @Override
      public void someMethod() {
          // 方法体
      }
      
  2. @Deprecated:

    • 用途: 用于标记一个类、方法或字段已经过时,不推荐使用。
    • 示例:
      @Deprecated
      public class DeprecatedClass {
          // 类的内容
      }
      
      @Deprecated
      public void deprecatedMethod() {
          // 方法体
      }
      
  3. @SuppressWarnings:

    • 用途: 用于抑制编译器警告。
    • 示例:
      @SuppressWarnings("unchecked")
      List<String> list = new ArrayList();
      
  4. @SafeVarargs:

    • 用途: 用于标记方法使用了可变参数,并且不会对泛型类型参数进行不安全的操作。
    • 示例:
      @SafeVarargs
      final <T> void safeVarargsMethod(T... elements) {
          // 方法体
      }
      
  5. @FunctionalInterface:

    • 用途: 用于标记一个接口是函数式接口,即只包含一个抽象方法。
    • 示例:
      @FunctionalInterface
      interface MyFunctionalInterface {
          void myMethod();
      }
      
  6. @SuppressWarnings:

    • 用途: 用于指定被注解元素的可见性,可用于类、接口、枚举、方法等。
    • 示例:
      @SuppressWarnings("unused")
      private int unusedField;
      

这只是一小部分Java内置注解的示例。Java内置注解为编写更健壮、可读性更强的代码提供了一些工具,同时也方便了工具和框架进行更高效的处理。在具体的开发中,还可以根据需要使用其他内置注解或自定义注解。

自定义注解

自定义注解是一种在Java中添加元数据信息的方式,允许程序员在代码中嵌入额外的信息,以便在编译、运行时或其他工具处理过程中进行使用。以下是详细的自定义注解的步骤和说明:

步骤一:使用 @interface 定义注解

使用 @interface 关键字定义自己的注解。注解元素的定义类似于接口的方法声明。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 定义自定义注解
@Retention(RetentionPolicy.RUNTIME) // 指定注解的保留期限
@Target({ElementType.TYPE, ElementType.METHOD}) // 指定注解可以标记的元素类型
public @interface MyCustomAnnotation {
    // 定义注解元素(属性)
    String value() default ""; // 注解元素可以有默认值
    int count() default 0;
}
  • @Retention(RetentionPolicy.RUNTIME): 指定注解的保留期限,RUNTIME 表示在运行时保留。
  • @Target({ElementType.TYPE, ElementType.METHOD}): 指定注解可以标记的元素类型,这里表示该注解可以标记在类和方法上。

步骤二:使用自定义注解

在代码中使用自定义注解,为注解元素提供具体的值。

@MyCustomAnnotation(value = "Example", count = 42)
public class MyClass {

    @MyCustomAnnotation(value = "Method", count = 10)
    public void myMethod() {
        // 方法体
    }
}

步骤三:获取注解信息

通过反射获取类和方法上的注解信息。

import java.lang.reflect.Method;

public class AnnotationExample {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<?> clazz = MyClass.class;

        // 获取类上的注解
        MyCustomAnnotation classAnnotation = clazz.getAnnotation(MyCustomAnnotation.class);
        System.out.println("Class Annotation Value: " + classAnnotation.value());
        System.out.println("Class Annotation Count: " + classAnnotation.count());

        // 获取方法上的注解
        Method method = clazz.getMethod("myMethod");
        MyCustomAnnotation methodAnnotation = method.getAnnotation(MyCustomAnnotation.class);
        System.out.println("Method Annotation Value: " + methodAnnotation.value());
        System.out.println("Method Annotation Count: " + methodAnnotation.count());
    }
}

通过这个简单的例子,你可以定义、使用和获取自定义注解的基本步骤。注解在实际开发中通常用于配置、文档生成、框架集成等场景。你可以根据具体需求定义不同的注解,并根据注解的信息进行相应的处理。

元注解

元注解是用于注解其他注解的注解,它们提供了对注解进行更灵活控制的机制。在Java中,元注解有四个,分别是 @Retention@Target@Documented@Inherited。以下是对每个元注解的详细说明:

  1. @Retention 元注解:

    • 用途: 指定被注解的保留期限,即注解在什么时候有效。
    • 可选值:
      • RetentionPolicy.SOURCE: 注解仅在源代码中保留,编译时丢弃。
      • RetentionPolicy.CLASS: 注解在编译时保留,但不会被加载到JVM中,默认值。
      • RetentionPolicy.RUNTIME: 注解在运行时保留,可以通过反射获取。
    • 示例:
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MyAnnotation {
          // 注解元素
      }
      
  2. @Target 元注解:

    • 用途: 指定注解可以标记的元素类型。
    • 可选值:
      • ElementType.TYPE: 类、接口、枚举类型。
      • ElementType.FIELD: 字段(包括枚举常量)。
      • ElementType.METHOD: 方法。
      • ElementType.PARAMETER: 方法参数。
      • ElementType.CONSTRUCTOR: 构造器。
      • ElementType.LOCAL_VARIABLE: 局部变量。
      • ElementType.ANNOTATION_TYPE: 注解类型。
      • ElementType.PACKAGE: 包。
    • 示例:
      @Target({ElementType.TYPE, ElementType.METHOD})
      public @interface MyAnnotation {
          // 注解元素
      }
      
  3. @Documented 元注解:

    • 用途: 表示该注解应该包含在JavaDoc文档中。
    • 示例:
      @Documented
      public @interface MyAnnotation {
          // 注解元素
      }
      
  4. @Inherited 元注解:

    • 用途: 表示该注解类型被自动继承。如果一个使用了 @Inherited 的注解被用于一个类,而这个类又被其它类继承,那么子类也会继承这个注解。
    • 示例:
      @Inherited
      public @interface MyAnnotation {
          // 注解元素
      }
      

这些元注解为注解提供了更多的控制和使用方式。例如,通过 @Retention 控制注解的保留期限,通过 @Target 指定注解可以标记的元素类型,通过 @Documented 使注解包含在文档中,通过 @Inherited 使注解能够被继承。这使得注解在不同场景中能够更灵活地发挥作用。

下面是一些使用元注解的示例,包括使用 @Retention@Target@Documented@Inherited 这几个元注解的场景:

1. 使用 @Retention 元注解:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

// 使用@Retention指定注解保留期限为运行时
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeRetentionAnnotation {
    String value() default "";
}

2. 使用 @Target 元注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

// 使用@Target指定注解可以标记的元素类型为方法和字段
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface MethodAndFieldAnnotation {
    String value() default "";
}

3. 使用 @Documented 元注解:

import java.lang.annotation.Documented;

// 使用@Documented使注解包含在JavaDoc文档中
@Documented
public @interface DocumentedAnnotation {
    String value() default "";
}

4. 使用 @Inherited 元注解:

import java.lang.annotation.Inherited;

// 使用@Inherited使注解能够被继承
@Inherited
public @interface InheritedAnnotation {
    String value() default "";
}

这些示例演示了如何使用元注解来控制注解的保留期限、标记的元素类型、是否包含在JavaDoc文档中以及是否能够被继承。在实际的开发中,这些元注解的使用会依赖于具体的需求和场景。

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值