Java 使用枚举与布尔?

Java 使用枚举与布尔?,java,hibernate,postgresql,Java,Hibernate,Postgresql,这可能起初看起来很普通,但事实上,我实际上是在做我需要使用的决定 我目前正在处理的是就业申请,这些申请需要在某个时间点标记为活动或非活动。提交应用程序时,它将默认为活动。由于某些原因,以后可能会将其设置为非活动。它只能是其中的一个,并且永远不能为null(以防发生任何更改) 我将其用于Java+Hibernate+PostgresSQL,以防这也会带来任何不同。我的第一反应是使用布尔值作为解决方案,以便它真正起到标志的作用,但我有一些同事建议使用枚举或整数作为状态,而不是标志 我已经用上面所有的

这可能起初看起来很普通,但事实上,我实际上是在做我需要使用的决定

我目前正在处理的是就业申请,这些申请需要在某个时间点标记为活动或非活动。提交应用程序时,它将默认为活动。由于某些原因,以后可能会将其设置为非活动。它只能是其中的一个,并且永远不能为null(以防发生任何更改)

我将其用于Java+Hibernate+PostgresSQL,以防这也会带来任何不同。我的第一反应是使用布尔值作为解决方案,以便它真正起到标志的作用,但我有一些同事建议使用枚举或整数作为状态,而不是标志

我已经用上面所有的解决方案解决了类似这样的问题,它们看起来都是透明的


有没有一种方法更适合这种情况?

如果只有true/false,那么布尔值比enum更有意义(开销更小)。建议:使用Boolean类而不是Boolean原语,这样可以检测“未知/未定义”状态以及true/false。

如果您可能需要更多的状态,而不是Active和Inactive,那么您是否希望使用and enum或int status标志?这使您的代码对于未来的状态更加灵活。

绝对不要使用int。使用enum是未来的证明;你必须自己决定什么更具可读性,以及是否适用。请注意,
boolean
boolean
不是一回事
Boolean
是一个类名,因此,
Boolean
类型的变量可以为空;而
boolean
是一个基元。

在您的例子中,有一个布尔值就足够了。因为需求是“主动的”,直接的答案可以是真的,也可以是假的。拥有一个枚举是可以的,但在我看来,布尔值是合适的,这完全取决于您的需求/规范。如果您只想将状态记录为“活动”或“非活动”,最好的方法是使用
boolean

public boolean isActive() {
  return status == Status.ACTIVE;
}
但是如果在将来,你会有这样的状态

  • 活跃的
  • 不活跃
  • 暂停
  • 封锁

Enums非常适合您。在您的情况下,现在,一个布尔值就足够了。不要过早地将事情过度复杂化,您将在系统的设计和开发中失去重点。

即使忽略将来添加更多状态类型的可能性(这当然是
enum
的一个很好的论据),我认为
enum
绝对是正确的选择。您不是在为布尔条件建模,而是在为应用程序的状态建模。想想看:应用程序的状态不是真的或假的,它是活动的或不活动的!状态
enum
将以最自然的方式表示这一点

使用enum还具有许多内置的优点,例如将每个状态的文本描述直接绑定到enum,这样就不必执行类似的操作

String text = application.isActive() ? "Active" : "Inactive";
你可以这么做

String text = application.getStatus().toString();
此外,您可以使用每个枚举以不同方式实现的抽象方法将特定行为直接绑定到每个状态,将特定数据与每个状态关联,等等

您还可以轻松允许基于状态的布尔
isActive
检查。。。如果只存储一个
布尔值
,就很难实现相反的目的

public boolean isActive() {
  return status == Status.ACTIVE;
}

null
不应该是有效状态的事实与此无关。。。只要确保任何存储状态的类(例如,您的
EmploymentApplication
类或任何其他类)在有人试图在其上设置
null
状态时抛出
NullPointerException

这两种方法都不可能吗

enum Status {
    ACTIVE(true), INACTIVE(false);
    private final boolean value;
    Status(boolean value) {
        this.value = value;
    }
    boolean getValue() {
        return this.value;
    }
}

这难道不能让你两全其美吗?它允许您使用名称为ACTIVE和INACTIVE的布尔值,而不是true和false?

我认为最好使用Enum而不是boolean。在有效的java中,它更喜欢两个元素枚举而不是布尔值。它还提出了以下优点。 代码更容易阅读 •代码更易于阅读 •代码更容易编写(特别是使用IDE) •无需查阅文件 •错误概率较小 •更好地促进API的发展

请参阅下面的链接以获取更多详细信息。

布尔人在工商界很少见 根据我为企业构建定制应用程序的经验,“女性/男性”或“开/关”等明显的二元性几乎总是演变或变形为多个值

  • “女性/男性”变为“未知/女性/男性”
  • “开/关”变为“开/暖/冷/关”
  • “未完成/已完成”变为“未完成/正在处理/已完成”
业务规则通常在早期不完全了解,或者随着时间的推移而改变

和我的许多同事一样,我学到了一条艰难的道路,那就是永远不要将这些值定义为布尔值。以后从布尔值更改为多个值既昂贵又有风险

Java枚举 与布尔值相比,枚举还有其他好处

Java枚举灵活且功能强大 Java中的
Enum
功能比大多数其他语言中的Enum灵活、强大且有用。看

在枚举定义中,您可以包含值的表示形式,以便向用户演示以及存储在数据库或文件中。这为程序员提供了一个方便的一站式服务,让他们可以阅读有关此枚举的所有信息以及如何在应用程序中使用它

这是一个完整的例子。这一类显示了我们在用户界面中使用的值以及我们保留的值

package com.basilbourque.example;

public enum Status {
    ACTIVE( "Active" , "active" ),
    INACTIVE( "Inactive" , "inactive" ),
    UNKNOWN( "Unknown" , "unknown" );

    private String displayName, codeName;

    Status ( String displayName , String codeName ) {
        this.displayName = displayName;
        this.codeName = codeName;
    }

    public String getDisplayName () { return this.displayName; }  // Or even add a `Locale` argument to support localization.

    public String getCodeName () { return this.codeName; }

    // To find a `Status` enum object matching input retrieved from a database.
    static public Status ofCodeName ( String codeName ) {
        // Loop each of the enum objects to find a match.
        for ( Status s : Status.values() ) {
            if ( s.getCodeName().equals( codeName ) ) { return s; }
        }
        throw new IllegalArgumentException( "No such Status code name as: " + codeName );
    }

    @Override
    public String toString() { return "app-status-" + this.getCodeName() ; }

}
将持久值转换回枚举对象 请注意,静态方法可以返回与从数据库检索到的持久值相匹配的
状态
对象:

Status s = Status.ofCodeName( myResultSet.getString( "code" ) ) ;
灵活的集合/地图 在Java中,枚举有自己的
Set
Map
实现,这两个实现在