我对如何在 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 方法的构造函数,这就是为什么我不明白构造函数和设置器之间使用有什么区别,请指教,干杯!
更改实例的name
值,该怎么办。当然,您不会为此使用构造函数,因为它会创建一个新实例。在这种情况下,您将使用setter
。
当然,如果你正在编写一个不可变的类,那么你不会给出任何setters
。实例字段中的任何修改都将创建一个新实例。
这里要了解的另一个重要点是,由于您在第二个代码中提供了参数化构造函数,因此编译器不会添加任何默认构造函数。因此,第二个类实际上没有任何 0-arg 构造函数。如果你想稍后使用它,那么你必须明确添加一个。
如果您有二传手,您可以在创建后随时更改该值。否则,构造后无法修改字段(它是不可变的(。
这一切都与name
变量的必要性有关。如果将其作为 setter,则可以在不设置 name
变量的情况下创建新的 Name
对象。如果它位于构造函数中,则无法在不指定 name
属性的情况下创建新的 Name
对象。
你可以同时做这两件事。这是您必须根据您的设计做出的选择。
设计类时,必须确保其实例始终处于一致状态。
在这种情况下,没有名称的类Name
可能被视为不一致。因此,在调用 setter 之前,您的类处于不一致的状态。在这种情况下,首选构造函数选项。
如果要允许重命名,也可以决定同时执行这两个操作(构造函数 + setter(。
更进一步:Java中的所有装箱类(整数,双精度,浮点数等(都是不可变的。因此,他们的内在价值没有二传手。
最简单的理解方法是查看用于描述两种方法的单词:
Setter - 可用于设置 name
,因此您可以在任何其他实例中更改 name
的值。
构造函数 - 我曾经构造过name
,所以它会构造一个新的name
,因此你不能用它来改变预先存在的
构造函数创建一个对象的新实例,您可以使用您希望它最初采用的变量实例化该对象。
二传手允许您在创建对象后更改变量的值。
Getters 允许您访问变量的值,而无需实际访问它们。
在你的问题中,在第一个代码片段之后,你提到:
它打印出123,它使用没有构造函数的setter方法
我需要对此做一个小的澄清。说这里没有构造函数实际上是不对的。您在这里得到的是默认构造函数。除非显式定义构造函数(参数化或非参数化(,否则存在默认构造函数。默认构造函数是在程序员未显式定义构造函数时编译器自动生成的一个构造函数。默认构造函数通常也称为空构造函数,因为它不保存任何参数。
现在进入正题。在您的第一个代码中:
private String name;
这是访问修饰符私有和字符串类型的实例变量,它保存的值null
.为什么?因为,默认构造函数将null
分配给您的实例变量。这就是为什么它被称为空构造函数。
使用 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
因为在主方法中,在对象创建期间:
Name a=new Name("123");
您在这些括号内提供了123
的值。这表明您正在创建一个参数化构造函数,该构造函数将采用 123
的字符串类型参数,该参数最终将分配给您的实例变量。
为了更好地理解这些关于getter-setter和构造函数的概念,请参考以下链接:
链接-1
链接-2
链接-3