【问题标题】:Java Setter and Constructor confusionJava Setter 和 Constructor 混淆
【发布时间】:2013-10-03 15:49:43
【问题描述】:

我对如何在Java中使用构造函数和setter有点困惑,请看下面的示例代码:

public class Name {
   private String name;

   public void setName(String name){
      this.name=name;
   }  
   public String getName(){
      return name;
   }
}

public static void main(String[] args) {
    Name a=new Name();
    a.setName("123");       
    System.out.println(a.getName());
}

它打印出123,它使用没有构造函数的setter方法,我还在下面写了其他代码:

public class Name {
   private String name;


   public Name(String nm){
      name=nm;
   }
   public String getName(){
      return name;
   }  
}



public static void main(String[] args) {
   Name a=new Name("123");

   System.out.println(a.getName());

}

这个也打印出123,使用的是没有setter方法的constructor,这就是为什么我不明白constructor和setter在使用上有什么区别,请指教,加油!

【问题讨论】:

标签: java constructor setter


【解决方案1】:

如果您想更改实例的name 的值怎么办。当然,您不会为此使用构造函数,因为它将创建一个新实例。在这种情况下,您将使用setter。

当然,如果你正在编写一个不可变类,那么你不会给出任何setters。实例字段中的任何修改都将创建一个新实例。

这里要理解的更重要的一点是,由于您在第二个代码中提供了参数化构造函数,编译器不会添加任何默认构造函数。因此,第二类实际上没有任何 0-arg 构造函数。如果你以后想使用它,那么你必须明确添加一个。

【讨论】:

  • thanks Rohit,是不是说constructor只是给了一个初始化的值,但是当我以后想改变这个值时,我需要使用setter方法来做?
  • @peiwang 是的,正是这样。
【解决方案2】:

如果您有一个 setter,您可以在创建后随时更改该值。否则,该字段在构造后无法修改(它是不可变的)。

【讨论】:

  • 嗨 Gabriel,根据您的评论,我无法更改第二个示例中的值,因为我正在使用构造函数来创建值,但是我如何更改这样的值: Name a=new Name ("123")--> Name a=new Name("456");
  • @peiwang 您并没有更改值,而是一起创建了一个新实例。
  • 您没有以这种方式更改name 字段,而是创建了一个新的Name 对象并将其分配给a。
【解决方案3】:

这一切都与name 变量的必要性有关。如果你把它作为一个setter,一个新的Name对象可以在不设置name变量的情况下创建。如果它在构造函数中,则无法在不指定name 属性的情况下创建新的Name 对象。

【讨论】:

    【解决方案4】:

    两者都可以。这是您必须根据您的设计做出的选择。

    当你设计一个类时,你必须确保它的实例总是处于一致的状态。

    在这种情况下,没有名称的类Name 可能被认为是不一致的。因此,在您调用 setter 之前,您的班级处于不一致的状态。在这种情况下,更喜欢构造函数选项。

    如果你想允许重命名,你也可以决定两者都做(构造函数 + 设置器)。

    更进一步:Java 中的所有装箱类(Integer、Double、Float 等)都是不可变的。因此,它们的嵌入价值没有设置器。

    【讨论】:

      【解决方案5】:

      了解它的最简单方法就是查看用于描述两种方法的词语:

      Setter - 可用于set name,因此您可以在任何其他实例中更改name 的值。

      构造函数 - 我曾经构造 name,所以它会构造一个新的name,因此你不能使用它更改预先存在的。

      【讨论】:

        【解决方案6】:

        构造函数创建一个对象的新实例,您可以使用您希望它最初采用的变量来实例化该对象。

        Setter 允许您在创建对象后更改变量的值。

        Getter 允许您访问变量的值,而无需实际访问它们。

        【讨论】:

          【解决方案7】:

          在您的问题中,在第一个代码 sn-p 之后,您提到:

          它打印出 123,它使用的是没有构造函数的 setter 方法

          我需要对此做一点澄清。说这里没有构造函数实际上是不对的。你在这里得到的是默认构造函数。 默认构造函数 存在,除非您明确定义构造函数,无论是参数化的还是非参数化的。 默认构造函数是编译器在程序员没有明确定义构造函数时自动生成的构造函数。 默认构造函数通常也被称为 nullary 构造函数,因为它不包含任何参数。

          现在进入正题。在您的第一个代码中:

          private String name; 
          

          这是您的 实例变量 访问修饰符 private 和 String 类型,它的值是 null。为什么?因为,默认构造函数将null 分配给您的实例变量。这就是为什么它被称为 nullary 构造函数。

          当您使用 setter 方法时,会为您的实例变量分配一个特定值。

          在这种情况下:

          public void setName(String name){
                this.name=name;
             } 
          

          公共 setter 方法在其参数中包含值 123,因为您在创建 Name 类的对象之后在 main 方法中提供了此值。像这样:

          a.setName("123");
          

          该值现在存储在您的实例变量中。

          好的,在您的第二个代码中:

          public Name(String nm){
                name=nm;
             }
          

          您在这里创建的是一个用户定义的参数化构造函数。只要有用户定义的构造函数,就不再创建默认构造函数。用户定义的构造函数用于为您的实例变量分配一个“非空”值。在这种情况下,您的构造函数在其参数中具有值123,因此123 将分配给您的实例变量name

          由于在您的 main 方法中,在对象创建期间:

          Name a=new Name("123");
          

          您在这些括号内提供了值123。这表明您正在创建一个参数化构造函数,它将采用123 的字符串类型参数,最终将分配给您的实例变量。

          为了更好地理解这些关于 getter-setter 和构造函数的概念,请参考以下链接:

          Link-1

          Link-2

          Link-3

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-08-01
            • 2023-03-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-15
            相关资源
            最近更新 更多