这是Java中正确的枚举实践吗?

Posted

技术标签:

【中文标题】这是Java中正确的枚举实践吗?【英文标题】:Is this proper enum practice in Java? 【发布时间】:2020-10-27 20:13:37 【问题描述】:

我刚开始学习 Java 中的枚举,虽然这个概念看起来很简单,但它的应用对我来说并不是很直观。我看到我可以将枚举放在类中,尽管它们本身就是类。

我在网上也看到有人说一个类中只能有一个枚举,或者你不应该将所有枚举放在一个类中,除非它们是私有的。

所以,我有点困惑,这段代码会是正确的枚举写法吗?

谢谢。

public class AirCraft 

    private AirType type;
    private AirFixTime maintainTime;
    
    private enum AirType
    
        HELICOPTER,
        AIRLINE,
        BALLOON,
        GLIDER;
    
    
    private enum AirFixTime
    
        WEEKLY,
        MONTHLY,
        YEARLY;
    

【问题讨论】:

它肯定会起作用,但是声明它们private有什么用?任何人都无法使用您的 AirCraft 类检索或设置引用它们的字段。 @Lino-Votedon'tsay 谢谢你是对的,这对他们来说是私人的没有多大意义。您认为这些枚举类在 AirCraft 类中是否可以?还是应该在自己的类文件中? 内部类/枚举仅在它们与封闭类一起使用时才有意义(例如,它们紧密耦合并且只有在一起使用时才真正有意义)。您的 AirType 在您的班级中是有意义的,但 AirFixTime 也可以用于不同的班级。 是的,它是可能的并且它有效(就像你可以拥有内部类和嵌套的静态类一样),但它是否是“正确”的选择是一个见仁见智的问题。 这个问题应该重新打开。在这里因为“基于意见”而被关闭是不合适的。该结束规则旨在避免在没有解决方案的情况下进行无休止的冗长讨论。这个问题可以用简短的解释巧妙地回答。 【参考方案1】:

从技术上讲,您的代码编写正确。枚举的使用取决于功能。请记住,访问修饰符用于管理您要分享或向他人展示的内容。现在,如果要在 AirCraft 内部使用枚举,您的代码是正确的。

看看this

【讨论】:

【参考方案2】:

您可以选择三个位置来放置枚举定义。

自己的类。 嵌套在另一个类中。 在本地,在方法内(Java 16,现在在 Java 15 中预览)

上下文是关键

您可以将枚举定义放在对您有意义的任何地方。这一切都取决于上下文。

如果您的枚举要在其他代码中单独使用,请将枚举放在自己的类中。 如果枚举真的只有在一个上下文中使用时才有意义 特定的类,然后嵌套枚举。 如果枚举对象仅在父类自己的源代码中使用,则将枚举定义为private。 如果枚举对象可能被处理父类对象的外部代码使用,则将嵌套类设置为public。例如,报表构建类可能希望通过分配的 AirCraft.Color 枚举对象对飞机部件进行排序,以将所有 safety-orange 部件聚集在一起。

例如,考虑将 Java 中内置的 MonthDayOfWeek 枚举类作为 java.time 类的一部分。这些枚举定义存在于它们自己独立的类中,因为它们可以在许多不同的上下文中使用,而无需其他 java.time 类的参与。这些枚举可单独用于工作流应用、销售报告、会计应用等。

相比之下,想象一个跟踪鼠标事件的 UI 框架。在那里我们可能会找到一个用于鼠标事件的Event 枚举,定义名为HOVERCLICKEDDRAGGED 的对象。这个枚举最好放在Mouse 类中,因为它只在外部鼠标处理类的上下文中有意义。

另一个例子,颜色。

列出所有在Cascading Style Sheets (CSS) 中命名的the standard colors 的枚举应该在它自己的类中,因为许多类型的代码都可能使用它。 列出飞机颜色编码部件中使用的颜色的枚举应该嵌套在 AirCraft 类中,这是它唯一有意义的上下文。

用法:

myWebPage.setBackground( CssColor.DARK_SLATE_GREY ) ;  // This enum could be used on its own with many classes in different frameworks. So define enum in a separate class..

myAircraft.getEmergencyStopButton().setColor( AirCraft.Color.SAFETY_ORANGE ) ;  // This enum is only ever used in contexts using its parent class, so nest the enum definition. 

如果嵌套,请考虑您的命名。我可能会将枚举命名为Color 而不是AircraftColor,因为嵌套的符号AirCraft.Color.x 可以明确上下文。另一方面,有些人喜欢使用static import 以便能够使用Color.x without the AirCraft. prefix(不是我的偏好)。

本地枚举

Java 16 中的新功能将是本地枚举(在 Java 15 中预览)。这意味着在方法中定义的枚举。

此新功能似乎仅作为新记录功能中的提及进行记录:JEP 384: Records (Second Preview)

private void demoLocalEnum ( )

    enum Color  PURPLE , SAFETY_ORANGE 
    System.out.println( Color.PURPLE ) ;

正如我们在此屏幕截图中看到的,枚举仅存在于包含其声明的方法中。同一个类的兄弟方法不知道枚举的存在。在此示例中,尝试在另一个方法中使用枚举会在 IDE 的代码编辑器中产生错误。

在您的枚举仅在一段代码中有意义的情况下使用它。如果您的枚举仅在单个方法中使用,那么将其声明为嵌套类会引起不必要的注意。隐藏在该方法中更整洁。

【讨论】:

谢谢。然后我会将我的枚举类嵌套在我的 AirCraft 类中。我猜将它们设置为默认/私有/公共应该不会有什么不同,因为我只是通过 AirCraft 类使用它们,对吧? @HelloWorld 我刚刚在这一点上添加了更多项目符号。一个一般规则:在你有一个已知的用例要求之前,把所有东西都写成private

以上是关于这是Java中正确的枚举实践吗?的主要内容,如果未能解决你的问题,请参考以下文章

这是对在 Java 中创建新对象的过程的正确描述吗?

Java枚举类型在switch语句中的正确用法

为啥没有为 java 枚举正确生成 Json?

这是正确使用new和delete - c ++ [重复]

Java编程最佳实践之多态

如何在 Java 中正确创建线程安全的单例工厂? [复制]