• Java 枚举类型与泛型-第13章


    Java 枚举类型与泛型-第13章

    1.枚举类型

    枚举类型是一种特殊的数据类型,用于表示一组有限的命名常量。枚举类型可以帮助您更清晰地定义和管理相关常量,并提供类型安全性。

    1.1使用枚举类型设置常量

    枚举类型是一种非常方便的方式来设置常量。我们可以创建一个枚举类型,其中包含需要的常量,然后在代码中使用这些常量。以下是如何使用枚举类型来设置常量的示例:

    public class ConstantsExample {
        // 定义一个枚举类型来表示颜色常量
        enum Color {
            RED, GREEN, BLUE
        }
    
        public static void main(String[] args) {
            // 使用枚举常量
            Color myColor = Color.BLUE;
            System.out.println("我的颜色是:" + myColor);
    
            // 使用switch语句根据不同的颜色执行不同的操作
            switch (myColor) {
                case RED:
                    System.out.println("我喜欢红色!");
                    break;
                case GREEN:
                    System.out.println("绿色也不错!");
                    break;
                case BLUE:
                    System.out.println("蓝色是我的最爱!");
                    break;
                default:
                    System.out.println("我不确定我的颜色是什么。");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在上述示例中,我们首先定义了一个名为Color的枚举类型,其中包含了三个颜色常量:REDGREENBLUE。然后,我们在main方法中使用枚举常量Color.BLUE来表示颜色,以及使用switch语句根据不同的颜色执行不同的操作。

    枚举类型使得代码更具可读性和可维护性,因为它将相关的常量组织在一起,并提供了一种类型安全的方式来处理它们。这在需要使用常量的情况下非常有用,因为它可以减少错误和提高代码的清晰度。

    1.2深入了解枚举类型

    1.枚举类型的常用方法

    枚举类型在Java中有一些常用的方法,这些方法使得操作和管理枚举常量更加方便。以下是一些常用的枚举类型方法:

    1. values(): 这个方法返回枚举类型的常量数组,允许您遍历所有的枚举常量。例如:Season.values()将返回包含所有季节的Season[]数组。
    2. valueOf(String name): 这个方法返回与给定名称匹配的枚举常量。通常用于将字符串转换为枚举常量。例如:Season.valueOf("SUMMER")将返回Season.SUMMER
    3. name(): 这个方法返回枚举常量的名称作为字符串。例如:Season.SUMMER.name()将返回字符串 “SUMMER”。
    4. ordinal(): 这个方法返回枚举常量在枚举类型中的位置(从0开始)。例如:Season.SUMMER.ordinal()将返回2,因为它是Season枚举中的第三个常量。

    这些方法可以帮助我们在处理枚举类型时执行各种操作,如遍历常量、根据名称查找常量或获取常量的位置。以下是一个示例:

    public class EnumMethodsExample {
        enum Day {
            MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
        }
    
        public static void main(String[] args) {
            // 使用values方法遍历所有常量
            Day[] days = Day.values();
            for (Day day : days) {
                System.out.println("Day: " + day.name() + ", Ordinal: " + day.ordinal());
            }
    
            // 使用valueOf方法根据名称查找常量
            Day tuesday = Day.valueOf("TUESDAY");
            System.out.println("Tuesday is " + tuesday);
    
            // 使用name方法获取常量的名称
            String fridayName = Day.FRIDAY.name();
            System.out.println("Friday's name is " + fridayName);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    上示例演示了如何使用这些常用的枚举方法来操作枚举常量。这些方法使得在处理枚举类型时更加便捷和有用。

    2.枚举类型中的构造方法

    枚举类型可以具有自定义构造方法,但这些构造方法在使用时有一些限制和特殊的用法。通常情况下,枚举类型的构造方法应该是私有的,以确保只有枚举常量内部可以调用它们。

    以下是一个示例,演示如何在枚举类型中定义和使用构造方法:

    enum Color {
        RED(255, 0, 0), // 枚举常量,每个常量都可以传入参数
        GREEN(0, 255, 0),
        BLUE(0, 0, 255);
    
        // 枚举类型的构造方法
        private int red;
        private int green;
        private int blue;
    
        private Color(int red, int green, int blue) {
            this.red = red;
            this.green = green;
            this.blue = blue;
        }
    
        public int getRed() {
            return red;
        }
    
        public int getGreen() {
            return green;
        }
    
        public int getBlue() {
            return blue;
        }
    }
    
    public class EnumConstructorExample {
        public static void main(String[] args) {
            Color myColor = Color.RED;
            System.out.println("My color is " + myColor);
            System.out.println("Red: " + myColor.getRed() + ", Green: " + myColor.getGreen() + ", Blue: " + myColor.getBlue());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在上述示例中,我们定义了一个名为Color的枚举类型,其中包含了三个颜色常量:REDGREENBLUE。每个常量都有一个构造方法,用于初始化redgreenblue成员变量。这些构造方法是私有的,只能在枚举内部访问。我们还定义了getter方法来获取颜色的RGB值。

    当我们使用枚举常量时,可以看到它们的构造方法被调用,并且可以使用getter方法来获取颜色的RGB值。这样,枚举类型允许您将自定义数据与每个枚举常量相关联。

    需要注意,枚举类型的构造方法在定义时是私有的,并且只能在枚举内部使用。这是因为枚举常量通常在定义时就被实例化,所以不允许外部代码创建新的枚举常量。

    2.泛型

    回顾向上转型与向下转型
    在这里插入图片描述

    泛型是一种Java编程语言的特性,它允许您编写通用的、类型安全的代码,以便在不同的数据类型上工作。泛型允许您在编写类、接口和方法时使用类型参数,这样您可以编写一次代码,然后在多种数据类型上重复使用,而不必为每种数据类型都编写新的代码。

    2.1定义泛型类

    要定义一个泛型类,我们需要在类名后面添加类型参数,并在类的内部使用这个类型参数来代表泛型类型。以下是一个简单的泛型类的示例:

    public class MyGenericClass {
        private T data;
    
        public MyGenericClass(T data) {
            this.data = data;
        }
    
        public T getData() {
            return data;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上述示例中,MyGenericClass 是一个泛型类,它具有一个类型参数 ,该参数代表一个泛型类型。构造方法 MyGenericClass(T data) 接受一个泛型类型的参数,并将其存储在私有成员变量 data 中。getData 方法返回存储在 data 中的泛型数据。

    还可以在创建泛型类的实例时指定具体的数据类型。例如:

    MyGenericClass integerGeneric = new MyGenericClass<>(42);
    int intValue = integerGeneric.getData();
    System.out.println("Integer Value: " + intValue);
    
    MyGenericClass stringGeneric = new MyGenericClass<>("Hello, Generics!");
    String stringValue = stringGeneric.getData();
    System.out.println("String Value: " + stringValue);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在上述示例中,我们创建了两个 MyGenericClass 的实例,一个使用整数类型 (Integer),另一个使用字符串类型 (String) 作为泛型类型。这允许我们在不同的数据类型上使用相同的泛型类,提高了代码的重用性和类型安全性

    2.2泛型的常规用法

    泛型在Java中有许多常规用法,它们有助于提高代码的可读性、类型安全性和重用性。以下是一些常见的泛型用法:

    1. 集合类使用泛型:Java标准库中的集合类如ArrayListHashMap等都使用泛型来存储元素,以确保集合中的元素是一种特定类型。这提供了类型安全性,避免了在编译时和运行时出现不合适的数据类型。

      List stringList = new ArrayList<>();
      Map intToStringMap = new HashMap<>();
      
      • 1
      • 2
    2. 自定义数据结构:您可以创建自定义的泛型数据结构,以便处理不同类型的数据。

      public class Pair {
          private T first;
          private U second;
          
          public Pair(T first, U second) {
              this.first = first;
              this.second = second;
          }
          
          public T getFirst() {
              return first;
          }
          
          public U getSecond() {
              return second;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    3. 泛型方法:您可以创建泛型方法,以便在方法内部使用类型参数。

      public  T findMax(T[] array) {
          T max = array[0];
          for (T element : array) {
              if (element.compareTo(max) > 0) {
                  max = element;
              }
          }
          return max;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    4. 通配符和限定通配符:通配符允许您编写灵活的代码,接受不确定的泛型类型,而限定通配符允许您指定通配符类型的范围。

      public void printList(List list) {
          for (Object element : list) {
              System.out.print(element + " ");
          }
      }
      
      public double sumOfNumbers(List numbers) {
          double sum = 0;
          for (Number number : numbers) {
              sum += number.doubleValue();
          }
          return sum;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    5. 泛型接口:您可以创建泛型接口,定义接口中的方法,这些方法可以在不同的实现中使用不同的泛型类型。

      interface ListConverter {
          List convertToList(T[] array);
      }
      
      • 1
      • 2
      • 3

    2.3泛型的高级用法

    泛型在Java中有许多高级用法,允许更高度的抽象和灵活性。以下是一些常见的高级泛型用法:

    1. 泛型通配符的上下界:通过使用通配符 ? 可以创建更灵活的泛型方法和类。通配符可以指定上限和下限,以便更精确地控制参数的类型。

      • 上限通配符 :表示通配符的类型必须是 T 类型或其子类型。
      • 下限通配符 :表示通配符的类型必须是 T 类型或其父类型。
      public double sumOfNumbers(List numbers) {
          double sum = 0;
          for (Number number : numbers) {
              sum += number.doubleValue();
          }
          return sum;
      }
      
      public void addIntegers(List list, int[] integers) {
          for (int num : integers) {
              list.add(num);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    2. 泛型通配符捕获:有时需要捕获通配符的类型以在方法内部使用。这可以通过将通配符类型存储在一个变量中来实现。

      public static  void copy(List source, List destination) {
          for (T item : source) {
              destination.add(item);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
    3. 泛型擦除和反射:在Java中,泛型信息在运行时被擦除,这会导致一些限制。但是,您可以使用反射来获取泛型类型信息。

      Class clazz = myGenericInstance.getClass();
      Type type = clazz.getGenericSuperclass();
      if (type instanceof ParameterizedType) {
          ParameterizedType paramType = (ParameterizedType) type;
          Type[] typeArgs = paramType.getActualTypeArguments();
          Class genericType = (Class) typeArgs[0];
          System.out.println("Generic type: " + genericType.getName());
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    4. 泛型方法的类型推断:从Java 7开始,编译器可以推断泛型方法的类型参数,无需显式指定。

      public static  T getFirst(List list) {
          return list.get(0);
      }
      
      List integers = Arrays.asList(1, 2, 3, 4, 5);
      Integer first = getFirst(integers); // 编译器可以推断类型参数
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    5. 泛型枚举:从Java 5开始,可以将泛型用于枚举,使得每个枚举常量可以有不同的类型参数。

      enum Result {
          SUCCESS, FAILURE;
          
          private T value;
          
          public T getValue() {
              return value;
          }
          
          public void setValue(T value) {
              this.value = value;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
  • 相关阅读:
    学习笔记17--汽车运动控制理论之现代控制理论
    ArkUI实战,深入浅出OpenHarmony应用开发
    Kubernetes-三大开放接口-初见
    DHTMLX Diagram JavaScript/HTML5 Pro Library:5.0
    Testing Library - About Queries
    Sqoop学习详细介绍!!
    C6657 GPIO16~31中断配置
    LLM系列 | 23:多模态大模型:浦语·灵笔InternLM-XComposer解读、实战和思考
    java计算机毕业设计校园失物招领管理系统源代码+系统+数据库+lw文档
    Linux高性能服务器编程——ch1笔记
  • 原文地址:https://blog.csdn.net/Sion_one/article/details/134088848