【问题标题】:Java enumerations support methods? But not in c#?Java 枚举支持方法?但不是在 C# 中?
【发布时间】:2011-12-17 14:51:45
【问题描述】:

我正在查看在 java 中执行单例的正确方法的代码:What is an efficient way to implement a singleton pattern in Java?

我有点迷茫,怎么给枚举添加方法?

 public enum Elvis {
       INSTANCE;
       private final String[] favoriteSongs =
           { "Hound Dog", "Heartbreak Hotel" };
       public void printFavorites() {
           System.out.println(Arrays.toString(favoriteSongs));
       }
   }

上面代码中的枚举对我来说甚至没有意义,你有符号:

INSTANCE;

那是一条正确的线吗?

我来自 c#,这个语法让我很好奇,我希望有人能解释或理解上述内容。

我猜这意味着 java 对枚举有更纯粹的想法,因为它可以有行为?

【问题讨论】:

  • 我不确定问题是什么。
  • 如果你问“为什么这种语法在 Java 中有效?”,那是因为在 Java 中设计枚举的人决定了。
  • 顺便说一句,对于“向枚举添加方法”的某些解释,扩展方法可能会有所帮助
  • 在我看来,您的示例就像是 C# 等效的 struct 的 hackish Java 解决方法。查看您提供的链接中的页面,看起来这是为了提高内存效率。但是,您必须考虑的一件大事是可维护性。 3 年后,开发人员是会看到代码并理解,还是默默地希望世界上所有的危险都在你头上?
  • @JimSchubert 该示例是在 Java 中实现单例对象的“正确”方式。在Class 上使用Enum 保证只会创建一个实例,因为在Java 中,EnumClass,因此您可以拥有所有相同的函数/变量。班级。默认情况下,C# 中的Structs 不是单例。它就像一个类一样具有可维护性,该类具有有关最终产品的适当文档,并记录了 Enum 的选择而不是 Class

标签: c# java enumeration


【解决方案1】:

你可以使用扩展方法

enum Elvis
{
  Instance
}

static class ElvisExtension
{
  private static readonly string[] FavoriteSongs = { "Hound Dog", "Heartbreak Hotel" };

  public static void PrintFavorites(this Elvis singleton)
  {
    Console.WriteLine(string.Join(", ", FavoriteSongs));
  }
}

用法:

Elvis.Instance.PrintFavorites();

【讨论】:

    【解决方案2】:

    为了给出一个稍微不同的答案,我认为你在问一个问题,Java 代码中的 INSTANCE; 行与以下 C# 示例中的 Instance 等效行:

    enum Elvis
    {
        Instance
    }
    

    这是您为 Java enum 创建 value 的方式。为了进一步举例,Java 枚举可以是:

    public enum Gender {
        MALE,
        FEMALE;
    }
    

    其中值类型为Gender.MALEGender.FEMALE,相当于:

    enum Gender
    {
        Male,
        Female
    }
    

    在 C# 中。

    如果我偏离了你的问题,我深表歉意。

    【讨论】:

      【解决方案3】:

      Java 中的枚举实际上是一个类。一种隐式扩展 java.lang.Enum。您在INSTANCE; 看到的特殊语法是枚举常量的声明。这将用于创建可以在代码中引用的枚举类的实例。事实上,您甚至可以为您的枚举创建一个非默认构造函数,并在常量声明中使用它。示例:

      public enum Test {
      
          INSTANCE("testing");
      
          private final String content;
          public Test(final String content) {
              super();
              this.content = content;
          }
      
      }
      

      将枚举视为真实对象具有一定的优势。将一些逻辑放入枚举中很方便,但也不应该被滥用。不过,在我看来,通过枚举的单例模式是一个不错的解决方案。

      【讨论】:

      • 那是一个很好的干净答案。简而言之,将 Java 枚举类型 a 视为常规类,它可以具有字段、构造函数和方法,但它只是带有一组预定义的实例。
      • @G_H 是INSTANCE 在这种情况下的特殊关键字,或者它可以是您选择的任何关键字?
      • @JimSchubert 您可以选择任何符合 Java 语言规范的名称。在这里没有特别的意义。不过,对枚举使用大写名称是标准做法。 INSTANCE 不是 Java 中的关键字,也不是小写字母。 instanceof 是,这样就不能用了。
      猜你喜欢
      • 1970-01-01
      • 2012-12-03
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多