首页 > 解决方案 > 如果 Enum 是期望元素之一,请检查 setter

问题描述

我想验证传递给 setter 的参数。

我有一个枚举,在这个枚举中我有一个汽车颜色。

在设置器中,我想检查传入的参数是否是我的 Color 枚举的一部分。

我正在寻找任何枚举方法,但我没有找到任何方法。我尝试使用正则表达式,但这不是一个好主意。

public enum Color {
  BLUE, RED, BLACK, WHITE
}

public void setColor(String color) {  
  //hear should be a method checking if a color contain enum  
  this.color = color;
}

我希望这个元素将包含一个枚举。

标签: javaenumssetter

解决方案


tl;博士

在设置器中,我想检查传入的参数是否是我的 Color 枚举的一部分。

错误的做法。您应该传递一个 object,您的枚举对象之一,而不是颜色名称的文本。

请参见poster.setBackgroundColor( Color.GREEN )下面的示例。

这就是在 Java 中使用枚举的要点:让编译器在编译时检查是否传递了有效值,而不是担心在运行时验证代码。

细节

看起来你在混淆一些东西。您可能混淆了枚举实例(一个常量)、它的硬编码名称以及您可能希望在运行时向用户显示的名称。

AnEnum是一种方便地实例化预定数量的类实例的方法,每个实例都被分配一个预定的名称。例如,MonthMonth.JANUARY通过Month.DECEMBER

常数名称

如果您想要实例的硬编码名称,按照约定全部大写(作为常量),然后调用toString.

String constantName = Month.JANUARY.toString() ;

一月

这里要非常清楚:String带有文本“JANUARY”的对象是由Month名为 的对象生成的JANUARY客体和客体是完全分开和不同的MonthString的文本String只是Month对象值的表示。

如果要通过该硬编码实例名称获取常量,请调用valueOf.

Month m = Month.valueOf( "JANUARY" ) ;  // Returns a `Month` object, not text.

尽量不要养成习惯valueOf。调用valueOf破坏了 Java 中枚举的目的和功能。您应该传递枚举对象,而不是它们的名称字符串。

显示名称

这些全大写的英文值可能足以用于日志记录和调试。但我们不太可能希望全大写英文文本出现在我们的用户界面和报告中。因此,在编写自己的代码时Enum,请添加一个名为类似的方法getDisplayName,如Month&所示DayOfWeek。指定TextStyle缩写的长度,以及Locale翻译中使用的人类语言和文化规范。

String output = m.getDisplayName( 
    TextStyle.FULL , 
    Locale.CANADA_FRENCH 
) ;

扬维尔

如何在您自己的枚举上实现它?好吧,您的枚举实际上是Enum. 因此,您的枚举实际上是一个与其他任何 Java 类一样的 Java 类,因为它可以具有构造函数和方法。为每个声明的枚举实例名称添加参数。

示例类

这是单个.java文件中的完整示例枚举类,带有main演示方法。

package work.basil.example;

import java.util.EnumSet;
import java.util.Set;

public enum Color {
    BLACK( "Black" ),                       // Pass arguments to each declared constant instant name, as you are really calling the constructor on each `static` `final` class constant object being automatically instantiated.
    GREY( "Grey" ),
    RED( "Red" ),
    GREEN( "Green" ),
    BLUE( "Blue" );

    private String displayName;             // Store the display name as a member variable on each enum instance.

    // Constructor     
    Color ( String displayName ) {          // Define a constructor taking the display name argument you passed above.
        this.displayName = displayName;
    }

    String getDisplayName ( ) {
        return this.displayName;
    }

    public static void main ( String[] args ) {
        System.out.println( "Color.BLACK.toString(): " + Color.BLACK.toString() );
        System.out.println( "Color.BLACK.getDisplayName(): " + Color.BLACK.getDisplayName() );

        Set < Color > monochromeColors = EnumSet.of( Color.BLACK , Color.GREY );
        boolean isRedMonochrome = monochromeColors.contains( Color.RED ); // ➙ false.
        System.out.println( "isRedMonochrome: " + isRedMonochrome );
    }
}

跑的时候。

Color.BLACK.toString(): 黑色

Color.BLACK.getDisplayName():黑色

isRedMonochrome: 假

注意使用EnumSet(or EnumMap) 来收集枚举实例。这里我们定义了一个以黑色和灰色命名的Color对象集合,但忽略了红色、绿色和蓝色。SetmonochromeColors

要使用您的枚举,请想象一个Poster具有海报背景颜色的 setter 方法的类。

Poster poster = new Poster() ;
poster.setBackgroundColor( Color.GREEN ) ;  

不需要文字 - 只需使用对象

请注意,没有涉及文本。不需要实例名称的字符串,也不需要显示名称。使用枚举实例是关于使用对象,而不是文本,而不是String. 使用 enum 对象可确保值有效,提供类型安全性,并使您的代码更具自我记录性。

使用名称

让我们添加需要这些名称的代码。首先用于记录,toStringPoster.

@Override public String toString() {
    return "Poster{ name=" + this.name + " | backgroundColor: " + this.backgroundColor.toString() + " }" ;  // Shows "GREEN"
}

在用户界面中展示海报时,显示颜色的名称。

Label label = new Label( 
    "Background color: " + 
    poster.getBackgroundColor().getDisplayName()   // Shows "Green".
) ;

推荐阅读