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

时间:2011-08-30 15:23:54

标签: java coding-style

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

  1. 创建用于设置每个属性的单独方法

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

    class Address{
        private String name;
        private String city;
    
        public setAddress(String name,String city) { ... }
    }
    
  3. 从以上两种方式来看,这在记忆的观点上是可取的?

7 个答案:

答案 0 :(得分:4)

通常的做法是使用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对象时,您需要处理同步/内存问题。

答案 1 :(得分:3)

我无法看到这两种方法在记忆方面有何不同。

选择在课程界面中最有意义的方法。

如果两个属性在逻辑上强烈相关,或者如果有一些不想暂时中断的类不变(甚至是暂时的),我建议使用方法2。

Address示例中,我肯定会使用两种setter方法,因为在谈论地址时,名称和城市是完全无关的。


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


经验法则:努力使您的班级界面清洁合理。

答案 2 :(得分:2)

为什么不使用方法#2

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

为您希望公开的每个字段使用单独的setter方法

通常的做法是为您希望公开的类中的每个字段设置一个setter方法(即您的第一个示例)。这是否是一个好的做法是值得商榷的,因为它迫使一个类成为mutable.如果可能的话,最好使对象成为不可变的for a number of reasons

使用构造函数初始化字段

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

public class Address {
    public String name;
    public String city;

    private Address(String name, String city) {
        this.name = name;
        this.city = city;
    }
}

使用构建器模式初始化字段

以下是一个完全替代的实现(受this article启发),它是Builder模式的变体。它模拟了对象的可变性而不会牺牲可读性。

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();

哪种方法使用更多内存?

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

答案 3 :(得分:1)

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

对内存没有任何影响,没有。

答案 4 :(得分:1)

JavaBean标准是为每个属性设置getter和setter:http://en.wikibooks.org/wiki/Java_Programming/Java_Beans。如果您不想遵循该标准惯例,那么它对您的商店最有意义。根据此线程上的其他答案,可能存在最小内存增量(如果有)。

答案 5 :(得分:1)

Nb.1毫无疑问。

并且您不会手动编写该代码,只会声明您的字段。

然后你让 Eclipse 为你完成剩下的工作。

在Eclipse中使用Source - >生成getter和setter。

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

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

答案 6 :(得分:0)

您通常会为每个属性编写一个setter和getter方法。

当一种方法足以设置所有属性时,我真的没有看到这种情况。在这种情况下,所有属性应该具有相同的值?或者您总是必须传递所有属性的参数。这两种情况都不是你想要的。所以你应该更喜欢你的第一种方法。