【问题标题】:Am I doing getters/setters the right way in Java?我在 Java 中以正确的方式做 getter/setter 吗?
【发布时间】:2010-05-12 01:02:28
【问题描述】:
public class Persona {
    int Codigo;
    String Nombre;

    public Persona(int Codigo, String Nombre){
        this.Codigo = Codigo;
        this.Nombre = Nombre;
    }

    public void setCodigo(int Codigo){
        this.Codigo = Codigo;
    }

    public int getCodigo(){
        return this.Codigo;
    }

    public void setNombre(String Nombre){
        this.Nombre = Nombre;
    }

    public String getNombre(){
        return this.Nombre;
    }


}

或者有更短(切实可行)的方法吗?

【问题讨论】:

    标签: java


    【解决方案1】:

    这取决于你所说的“做”是什么意思。 getter 和 setter 比公共领域更好 - 但你真的需要它们吗?

    • 您是否需要公开这些信息,或者只是使用它来完成其他操作?
    • 如果您确实需要公开它,您是否确实需要您的类型在 setter 中是可变的?不可变类型往往更容易推理、处理线程等。

    只是为了“纠正”您当前的设计,假设您确实想要 getter 和 setter,我会将其更改为:

    public final class Persona {
        private int codigo;
        private String nombre;
    
        public Persona(int codigo, String nombre) {
            this.codigo = codigo;
            this.nombre = nombre;
        }
    
        public void setCodigo(int codigo) {
            this.codigo = codigo;
        }
    
        public int getCodigo() {
            return codigo;
        }
    
        public void setNombre(String nombre) {
            this.nombre = nombre;
        }
    
        public String getNombre() {
            return nombre;
        }
    }
    

    主要变化在于字段的大小写以及字段的私有化。就我个人而言,我也不使用“this”。我不需要的地方。我在 () 和 { 之间也有一个空格。这些都是个人喜好。

    最后,我创建了 final 类——我坚信“为继承而设计或禁止它”——如果您确实需要从该类派生,请考虑哪种类型你想支持的专业。

    【讨论】:

    • 仅供参考,“return Codigo”中的错字。
    • +1 表示final 类。回想起来,默认情况下使用 final 类并使用特殊关键字来缓解限制会好得多。
    • @Alexander:我也是。 C# 更接近了,默认情况下将 methods 设为非虚拟 - 但类仍然未密封:(
    【解决方案2】:

    你做得对。不幸的是,Java 没有像许多其他语言那样更紧凑的方法来定义 getter 和 setter。

    需要考虑的一件事——如果您只打算在对象构造中设置这些值,则不需要设置器。而且,如果您从不打算直接获取值,请不要定义 getter。只需在需要时定义它们即可。

    这里有一篇发人深省(如果有点极端)的文章:Why getter and setter methods are evil

    【讨论】:

      【解决方案3】:

      这是在 Java 中正确的做法(除了变量通常以小写字母开头)。您还可以使用自动生成 getter/setter 的 groovy

      class Persona {
          int Codigo
          String Nombre
      }
      

      这实际上是一样的

      正如其他人所提到的,如果您不需要 setter,则应避免使用它们并将变量设为 final。不可变对象以后不太可能成为错误的来源。

      【讨论】:

      • 如果您将所有字段设为最终字段,您将需要一个构造函数,这是一件好事。
      【解决方案4】:

      这对于 Java 是正确的。请注意,由于您将这两个值都传递给构造函数,因此您可以删除设置器,将字段标记为 final,然后这个类将是 immutable

      【讨论】:

        【解决方案5】:

        对我来说,这看起来像是很好的 setter/getter。但是,如果您将两个值都传递给构造函数,您确定两个 setter/getter 都需要吗?在这种情况下,看起来只有吸气剂就足够了。此外,如果您决定坚持将 CodigoNombre 传递给构造函数,并删除 setter 类,则应将它们设为 final ,即不可变。

        另外一点是不要大写CodigoNombrecodigonombre是推荐的形式。方法和字段的驼峰式大小写,仅大写类、接口和常量。

        【讨论】:

        • 我在想类似 (C#) public string Name {get;set;} :( 这不是 Java 的情况吗?
        • @Sergio。不,没有像 Java 那样的等价物
        • Java 没有属性的概念,更不用说自动属性(这是您发布的语法)。
        【解决方案6】:

        是的,看起来不错。尽管您不应该将变量名大写。

        【讨论】:

          【解决方案7】:

          您可能希望将成员变量 Nombre 和 Cordigo 设为“私有”。因为,这就是使用 getter/setter 的全部意义所在。

          更重要的是要了解为什么要使用 getter/setter。
          一个好处是您可以在这些方法中添加额外的检查(如限制,如果它是一个数字)。此外,如果您的实现在未来发生变化,它们更容易维护。

          【讨论】:

            【解决方案8】:

            你的变量不是private,它们是默认的。所以它们对同一个package 中的类是公开的。你可能想让他们private。尽管几乎总是需要 getter,但并不总是需要 setter。

            【讨论】:

              【解决方案9】:

              这些字段应该是私有的。原因是Encapsulation。您希望对使用您的 Persona 类的任何其他类隐藏实现细节。您可能有一天想要在codigo 上强制执行最小值和最大值,或者确保它在一组固定的值中,您可以在setCodigo() 方法中执行此操作,而无需任何客户端代码知道它。仅使用公共字段,您无法拦截该字段的突变并对其产生影响。

              public final class Persona 
              {
                  private int codigo;
                  private String nombre;
              
                  public Persona(final int codigo, final String nombre)
                  {
                      this.codigo = codigo;
                      this.nombre = nombre;
                  }
              
                  public void setCodigo(final int codigo)
                  {
                      this.codigo = codigo;
                  }
              
                  public int getCodigo()
                  {
                      return this.codigo;
                  }
              
                  public void setNombre(final String nombre)
                  {
                      this.nombre = nombre;
                  }
              
                  public String getNombre()
                  {
                      return this.nombre;
                  }
              }
              

              我还为您修复了大括号对齐 :-) 对所有实例变量使用this. 也是很好的编码习惯。显式优于隐式。

              【讨论】:

                【解决方案10】:

                就像 Jon 说的,你需要有充分的理由需要 getter/setter。考虑一个不可变类作为您的案例的替代方案。

                public final class Persona {
                    private final int codigo;
                    private final String nombre;
                
                    public Persona(int codigo, String nombre) {
                        this.codigo = codigo;
                        this.nombre = nombre;
                    }
                
                    public int getCodigo() {
                        return codigo;
                    }
                
                    public String getNombre() {
                        return nombre;
                    }
                }
                

                【讨论】:

                • 如果要使类不可变,还应该使成员变量final
                猜你喜欢
                • 2015-02-07
                • 1970-01-01
                • 2016-08-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-09-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多