Java Setter和构造函数混淆

Java Setter和构造函数混淆,java,constructor,setter,Java,Constructor,Setter,我对如何在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) {

我对如何在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());
}
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方法,我还编写了以下其他代码:

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());
}
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方法,这就是为什么我不理解构造函数和setter之间使用的区别,请建议,干杯

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

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


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

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

您可以同时执行这两项操作。这是您必须根据设计做出的选择

设计类时,必须确保其实例始终处于一致状态

在这种情况下,没有名称的类
名称
可能被视为不一致。因此,在调用setter之前,类处于不一致的状态。在这种情况下,首选构造函数选项

如果您想允许重命名,您还可以决定同时使用这两种方法(构造函数+设置器)


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

这一切都与
名称
变量的必要性有关。如果将其作为setter,则可以创建一个新的
Name
对象,而无需设置
Name
变量。如果它在构造函数中,如果不指定
Name
属性,就无法创建新的
Name
对象。

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

Setter-可用于设置
名称
,因此您可以在任何其他实例中更改
名称
的值


构造函数-我曾经构造
名称
,因此它将构造一个新的
名称
,因此您无法使用它来更改先前存在的名称。

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

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


getter允许您访问变量的值,而实际上不允许您访问它们

在您的问题中,在第一个代码片段之后,您提到:

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

我需要对此做一点澄清。实际上说这里没有构造函数是不对的。这里得到的是默认构造函数。除非显式定义构造函数(参数化或非参数化),否则默认构造函数存在。默认构造函数是编译器在程序员没有显式定义构造函数时自动生成的一个构造函数。默认构造函数通常也称为空构造函数,因为它不包含任何参数

现在说到点子上。在您的第一个代码中:

private String name; 
这是access修饰符private和type String的实例变量,它包含值
null
。为什么?因为,默认构造函数将
null
分配给实例变量。这就是为什么它被称为空构造函数

使用setter方法时,会为实例变量指定一个特定值

在这种情况下:

public void setName(String name){
      this.name=name;
   } 
公共setter方法在其参数中包含值
123
,因为在创建
Name
类的对象后,您在主方法中提供了该值。像这样:

a.setName("123");
该值现在存储在实例变量中

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

public Name(String nm){
      name=nm;
   }
这里创建的是一个用户定义的参数化构造函数。只要有用户定义的构造函数,就不再创建默认构造函数。用户定义的构造函数用于为实例变量分配一个“NOTNULL”值。在这种情况下,构造函数的参数中有值
123
,因此
123
将被分配给实例变量
name

因为在主方法中,在对象创建期间:

Name a=new Name("123");
您在这些括号内提供了值
123
。这表示您正在创建一个参数化构造函数,该构造函数将采用字符串类型参数
123
,该参数最终将被分配给实例变量

为了更好地理解这些关于getters setter和constructor的概念,请参考以下链接:


请参阅Java教程:在第二个示例中,在构造名称(不可变对象)后,任何人都不能更改名称;与第一个不同,您可以随时将名称更改为现有对象(可变对象)。谢谢Rohit,这是否意味着构造函数只给出一个初始化值,但当我以后要更改此值时,我需要使用setter方法来执行此操作?@peiwang是的,正是这样。嗨,Gabriel,根据您的评论,我无法更改第二个示例中的值,因为我正在使用构造函数来创建值,但是我可以这样更改值:Name a=new Name(“123”)-->Name a=new Name(“456”)@peiwang你没有改变值,b