Java 在类中声明方法的首选方法

Java 在类中声明方法的首选方法,java,coding-style,Java,Coding Style,我对设置信息的类中的方法创建有疑问 为设置每个属性创建单独的方法 class Address{ private String name; private String city; public setName(String name) { ... } public setCity(String name) { ... } } 创建用于设置所有属性的单一方法 class Address{ private String name; private

我对设置信息的类中的方法创建有疑问

  • 为设置每个属性创建单独的方法

    class Address{
        private String name;
        private String city;
    
        public setName(String name) { ... }
        public setCity(String name) { ... }
    }
    
  • 创建用于设置所有属性的单一方法

    class Address{
        private String name;
        private String city;
    
        public setAddress(String name,String city) { ... }
    }
    

  • 从以上两个方面来看,从记忆的角度来看哪一个更可取?

    这不是一个明确的问题。你的意思是,你愿意有两种方法,比如
    setFoo(String)
    setBar(int)
    ,还是一种方法,比如
    setFooBar(String,int)
    ?这实际上取决于这些属性在逻辑上是否不同,在这种情况下,您需要单独的方法,或者将它们设置在一起是否经常(或仅)有意义。你可以两者都提供


    这两种方法都不会影响记忆,不会。我看不出这两种方法在记忆方面有什么不同

    选择在类的接口中最有意义的方法

    只有当两个属性在逻辑上有很强的相关性,或者存在一些您不想临时破坏的类不变量时,我建议使用方法2

    在您的
    地址
    示例中,我肯定会使用两种setter方法,因为当谈到地址时,名称和城市是完全不相关的


    对于一般的方法我想说,是否将一个方法一分为二对内存消耗几乎没有影响。每个对象都没有分配自己的方法集。包含方法的内存在类的所有实例之间共享



    经验法则:努力使类的接口干净且合乎逻辑。通常为每个属性编写一个setter和一个getter方法


    我真的不认为一种方法就足以设置所有属性。在这种情况下,所有属性都应该具有相同的值?或者,您必须始终为所有属性传递参数。这两种情况都不是你真正想要的。所以你显然应该更喜欢你的第一种方法。

    为什么不使用方法2

    不推荐使用第二个示例,因为如果向Address类添加了一个新字段,那么是将其添加到现有的setter方法中,还是创建一个新的setter方法?如果将其添加到现有的setter方法中,那么调用该方法的任何类都将被破坏。如果您创建了一个新的setter方法,那么任何想要使用该类的人都会感到困惑,为什么某些字段会以这种方式分组在一起,而其他字段则不会

    对要公开的每个字段使用单独的setter方法

    通常的做法是为类中希望公开的每个字段(即第一个示例)使用一个setter方法。这是否是一个好的实践是值得商榷的,因为它强制一个类是不可变的,如果可能的话,最好使一个对象是不可变的

    使用构造函数初始化字段

    使类不可变的一种方法是去掉setter方法,而是通过类构造函数使字段可设置,如下所示。以这种方式实现它的缺点是,如果您的类有很多字段,则可能会导致大型的、不可读的构造函数调用

    public class Address {
        public String name;
        public String city;
    
        private Address(String name, String city) {
            this.name = name;
            this.city = city;
        }
    }
    
    使用生成器模式初始化字段

    下面是一个完全替代的实现(受启发),它是该模式的一个变体。它在不牺牲可读性的情况下模拟对象的易变性

    public class Address {
        public String name;
        public String city;
    
        private Address() {}
    
        private void setName(String name) {
            this.name = name;
        }
    
        private void setCity(String city) {
            this.city = city;
        }
    
        static class Builder {
            private Address address = new Address();
    
            public Builder name(String name) {
                address.setName(name);
                return this;
            }
    
            public Builder city(String city) {
                address.setCity(city);
                return this;
            }
    
            public Address build() {
                return address;
            }
        }
    }
    
    使用上述类,您可以创建Address类的不可变实例,如下所示:

    Address address = new Address.Builder()
            .name("Mansoor's address")
            .city("Toronto")
            .build();
    
    哪种方法使用更多内存?


    从内存的角度来看,不应该有任何区别,因为内存中类的大小取决于类中的字段。因为这三个实现都有相同的字段,所以无论使用哪种方法,它们都应该占用相同的内存空间。

    JavaBean标准是每个属性都有getter和setter:。如果你不想遵循标准惯例,那么这对你的商店来说是最有意义的。根据此线程上的其他答案,可能存在最小内存增量(如果有的话)。

    Nb.1毫无疑问

    您不需要手工编写代码,只需要声明字段

    然后让Eclipse为您完成其余的工作

    在Eclipse中,使用源-->生成getter和setter

    与#2非常相似的构造是在对象构造函数中完成的


    关于记忆的最新问题。在生产代码中,不要担心这两种方式之间的内存差异。

    通常的做法是使用JavaBean风格

    class Address {
      private String name;
      private String city;
    
      public setName(String name){
        this.name = name;
      }
    
      public String getName() {
         return name;
      }
    
      public setCity(String city){
         this.city = city;
      }
    
      public getCity() {
        return city;
      }
    
    }

    另一个与第二种方法非常相似的常见做法是创建不可变对象。参数被传递给构造函数,而不是大setter方法

    class Address {
      private final String name;
      private final String city;
    
      public Address(String name, String city) {
          this.name = name;
          this.city = city;
      }
    
      public String getName() {
         return name;
      }
    
      public getCity() {
        return city;
      }
    }
    
    从内存的角度来看,区别在于第二个示例是在构造函数中设置所有属性,并且所有这些属性都是不可变的。通常,当多线程使用时,以这种方式构造的对象更安全


    在第二个示例中,不需要同步。当多个线程使用标准JavaBean对象时,您需要处理同步/内存问题。

    向我们展示这两种方法的代码示例的含义。这个类的用途是什么?它是一个值对象吗?您是否需要独立设置每个值?创建对象后,这些值是否必须更改?你说的“记忆观点”是什么意思?人类记忆还是计算机记忆?第一个例子是好的,第二个例子是坏的。使用构造函数。如果你真的在寻找可变对象,那么getter/setter就可以了。然而,不可变对象越来越常见:+1 SyntaxT3rr0r。我完全同意这种观点。它确实意味着