【问题标题】:Which of these ways is better in Java? [duplicate]这些方法中哪一种在 Java 中更好? [复制]
【发布时间】:2014-07-30 02:47:49
【问题描述】:

我想创建一个像枚举一样工作的静态类,但使用字符串值。 以下哪种方式提取已创建类的完整实例最安全?

public class Name 
{

    public static final Name MY_NAME = new Name("Chris", "Doe");

    public String firstName;
    public String lastName;

    public Name(firstname, lastname)
    {
        this.firstName = firstname;
        this.lastName = lastname;
    }
}

public class Name 
{
    public String firstName;
    public String lastName;

    public Name(firstname, lastname)
    {
        this.firstName = firstname;
        this.lastName = lastname;
    }

    public static Name myName()
    {
        return new Name("Chris", "Doe");
    }
}

【问题讨论】:

  • 在第二种模式中,为什么要使用硬编码值?
  • 两者不相同;每次调用 myName() 时,第二个将返回一个新的 Name 实例,而第一个将返回相同的实例(除非序列化/并发恶作剧)
  • 第一个是更好的选择,因为您正在为字符串创建最终字段。
  • 如果你想创建类似枚举的东西,那么为什么不使用枚举呢?
  • 从不。我的意思是永远不要像在第二个示例中那样公开非静态、非最终字段。

标签: java class design-patterns static static-methods


【解决方案1】:

最安全?我不确定你的意思。

就最佳实践而言,第二个可能是浪费的,因为它会在每次调用 myName() 时分配一个新的 Name 实例。另一个使用常量,因此可以节省更多内存。

所有这些在小型应用程序中都是相对微不足道的。

如果你想让你的类模拟enum,那么常量肯定是要走的路,因为enum 的值只初始化一次。

如果您不知道 enum 究竟是什么,这里将是您的类的示例实现:

public enum Name {

    MY_NAME ("Chris", "Doe");

    private final String firstName;
    private final String lastName;

    private Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

...然后您可以简单地参考Name.MY_NAME

【讨论】:

  • 这在某种程度上引出了“为什么首先没有枚举”的问题,尤其是当您对值进行硬编码时。甚至枚举也可以在某种程度上是动态的。
  • @Rogue 我同意你最好使用enum,但我认为这不是一个合适的答案,哈哈。
  • @JeffGohlke-使用enum演示很好的解释。
  • 值得注意的是,枚举构造函数上的private 修饰符是完全可选的,因为枚举构造函数无论如何都是隐式的private。尝试将其设置为其他任何内容也是编译时错误。
  • @JonK 当然。我只是更喜欢对我的访问修饰符非常明确。 :)
【解决方案2】:

我想选择第一个,因为第一个包含 static final Name MY_NAME 在第二种情况下,每次都会返回 new Name 实例你调用 myName() method 导致内存浪费。所以,最好选择第一个。

因此,要提取已创建类的完整实例,您应该使用第一个。

另外,谈到enum----你持有常量值,你的static field final Name MY_NAME实例将达到目的,你应该坚持第一个声明----从而支持你对枚举的需求也不会浪费内存!

【讨论】:

    【解决方案3】:

    采用第一种方法,

    创建您的public static 类实例,使您的类成为最终类,使其不能扩展,并使构造函数私有,因此它不能在您的类之外实例化

    第二种方法的缺陷是,您的静态方法 myName 每次都会创建新的 Name 实例,这是不必要的

    【讨论】:

      【解决方案4】:

      如果您只需要一个具有固定值的对象实例,为什么还要使用成员变量呢? 无论您如何使用对象,这种方式都是线程安全的。

      public class Name 
      {
          public String getFirstName() {
              return "Chris"
          }
      
          public String getFirstName() {
              return "Doe"
          }
      }
      

      如果你必须有成员变量,那么:

      public class Name 
      {
          public final String firstName = "Chris"
          public final String lastName = "Doe"
      }
      

      但正如其他人建议的那样,只需使用枚举:

      public enum Name {
          me("Chris", "Doe");
          private String firstName;
          private String lastName;
      
          Name(String firstName, String lastName) {
              this.firstName = firstName;
              this.lastName = lastName;
          }
      
          public String getFirstName() {
              return firstName;
          }
      
          public void setFirstName(String firstName) {
              this.firstName = firstName;
          }
      
          public String getLastName() {
              return lastName;
          }
      
          public void setLastName(String lastName) {
              this.lastName = lastName;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-07-11
        • 2013-01-28
        • 1970-01-01
        • 1970-01-01
        • 2018-06-27
        • 1970-01-01
        • 1970-01-01
        • 2018-05-24
        • 1970-01-01
        相关资源
        最近更新 更多