我对使用getter / setter和构造函数感到有点困惑(参见下面的代码示例)
public class ExampleClass {
private int value = 0;
public ExampleClass () {
value = 0;
}
public ExampleClass (int i) {
this.value = i;
}
public int getValue() {
return value;
}
public void setValue(int val) {
this.value = val;
}
public static void main(String[] args) {
ExampleClass example = new ExampleClass (20);
example.setValue(20);
//Both lines above do same thing - why use constructor?
System.out.println(example.getvalue());
}
}
我所学到的只是我们需要getter / setters以确保安全性,并且它们也可以用于稍后更改或编辑值。
我的问题是,如果构造函数是初始化点并且始终存在默认构造函数,为什么要使用带参数的构造函数来初始化值而不是getter / setters?。不会使用getter和setter提供安全性,并且能够在任何阶段轻松更改值。请为我澄清这一点。
答案 0 :(得分:21)
实际上它并不总是存在。默认构造函数是由编译器提供的构造函数(当然它是一个无参数构造函数)仅当类中没有定义其他构造函数时默认构造函数始终存在
为什么我们使用带参数的构造函数初始化值而不是set get
因为可能存在这样的情况:只有在初始化时提供所有值并且没有默认值时才能始终创建对象。因此必须提供所有值,否则代码将无法编译。
考虑这个Book
类
public class Book {
private String title;
private String author;
public Book(String title, String author){
this.title = title;
this.author = author;
}
//getters and setters here
}
考虑只有在有title
和author
的情况下才能创建图书的情况。
new Book()
因为没有arg构造函数而且编译器不会提供一个,因为已经定义了一个构造函数。 new Book()
,因为我们的条件不符合,因为每本书都需要一个标题和作者。这是参数化构造函数有用的条件。
答案 1 :(得分:8)
有时,在创建类的新对象时,必须提供一些值。例如,当连接到数据库并创建Connection类对象时,您必须提供连接字符串,以便它知道您要连接到什么。在没有指定目标数据库的情况下创建新连接将毫无用处,对吧?
另外,看看这个
Foo foo=new Foo(1,2,3,4,5,6,7);
和这个
Foo foo=new Foo();
foo.setP1(1);
foo.setP2(2);
foo.setP3(3);
foo.setP4(4);
foo.setP5(5);
foo.setP6(6);
foo.setP7(7);
第一个看起来更好,对吧?
答案 2 :(得分:6)
我的问题是,如果构造函数是初始化点和 默认构造函数总是在那里,所以我们使用构造函数 用于初始化值的参数而不是set get。
如果你考虑一个对象转换到不同的状态,那么有一个参数化的构造函数以及setter和getter是有意义的。让我尝试一个现实生活场景:想想一个Employee类,一个新员工加入,你不知道很多细节,但很少,你创建了Employee的对象,其属性的defualt和基值。您需要在系统中注册员工,因此您使用了参数化构造函数。获得有关员工的更多详细信息后,可以使用getter和setter来更新属性。
答案 3 :(得分:5)
这纯粹取决于你的编码风格。但IMO,我会使用参数化构造函数:
初始化那些不应更改的值。 (如person对象的username参数)
初始化这些值,而不设置哪个,对象将处于无效状态。
说,您正在向方法发送登录参数。您可以在这些方式中使用
Login obj = new Login();
obj.setUsername("user");
obj.setPassword("pw")// what if someone commented this out, or you forget to call it
and otherway,
Login obj = new Login("user", "pw");
虽然您可以在第一种情况下设置用户名后立即发送Login对象,但在接收结束时它将无效。但第二种方法不容易出现错误,bcz必须传递所有必需的参数。
答案 4 :(得分:3)
有时您无需在创建时将所有字段设置为特定值。例如,当你制作一个数组时。另外,正如已经说过的那样,使用getter时更安全 - 你无法获得nullpointer。
在使用参数定义构造函数时,请记住编写默认构造函数。或者一定不要使用它。
答案 5 :(得分:3)
首先,两种方法:构造函数和Setter是更改对象属性的安全方法。期望从类作者公开或不安全地修改实例。
如果您还没有编写默认构造函数,则始终提供默认构造函数:
// Example of a Class with a Default Constructor
public class GetSet {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static void main(String[] args) {
// Theres a implicit Default Constructor here
// Its ok to do that
// GetSet obj = new GetSet();
GetSet obj = new GetSet();
}
}
// Example of a Class without a Default Constructor
public class GetSet2 {
public GetSet2(String value) {
this.value = value;
}
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static void main(String[] args) {
// GetSet2 obj = new GetSet2(); // compile time error
// Default constructor is not provided, since u wrote one
}
}
2.关于哪个更好:使用构造函数或通过setter,它取决于你想要的。如果您只修改现有对象的属性,则可以使用setter,或者对于完全填充的对象,您可能更喜欢构造函数。
// Example of modifing an obj via Setter and Constructor
public class GetSet3 {
public GetSet3(String value1, String value2, String value3, String value4) {
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
this.value4 = value4;
}
private String value1;
private String value2;
private String value3;
private String value4;
// ... Getters and Setters
public static void main(String[] args) {
// Its easier to this
GetSet3 obj;
obj= new GetSet3("j", "a", "v", "a");
// instead that
// its also easy to forget or do something wrong
// when u have a lot of attributes to set
obj.setValue1("j");
obj.setValue2("a");
obj.setValue3("v");
obj.setValue4("a");
}
}
答案 6 :(得分:2)
只是为了让它变得更容易。使用构造函数所需的代码少于创建对象和使用setter。
答案 7 :(得分:2)
通过构造函数初始化对象变量以避免nullpointers更容易,更安全。
如果在不首先初始化变量的情况下实例化对象,并对其中一个空变量执行get操作,则可能会在运行时获得nullpointer异常,因为您忘记手动设置其值。
另一方面,如果您始终在默认构造函数中初始化对象变量,那么在运行时期间获得nullpointer异常的风险会大大降低,因为除非您通过setter专门设置它们,否则您的所有变量都不能为null(这是不推荐的。)
答案 8 :(得分:2)
带参数的构造函数使您可以获得完全构造的对象。如果要使用默认值,则必须确保使用setter设置字段。在设置某个属性期间,假设抛出异常,现在您有一个不可用的对象。在某些情况下,setter不会暴露,而是吸气剂。在这些情况下,使用带有参数的构造函数或命名构造函数是正确的选项。简而言之,getter和setter确实有自己的重要性,而不是初始化对象。
答案 9 :(得分:2)
因为在构造函数中将值设置为参数时,使用更少,更优雅和更易读的代码来编写它。此外,有时某些字段对于对象是必不可少的,因此参数构造函数会阻止用户创建一个对象,省略对象功能的必要字段。一个人虽然没有“痴迷”来打电话给安装人员。
答案 10 :(得分:0)
要回答这个问题,我说通过写getters / setters,我们创建了一条规定以在将来添加任何验证方法,目前,没有验证,但是如果将来出现任何问题,我们只需在以下步骤中添加验证逻辑即可塞特犬。
我们还可以在构造函数中编写逻辑/验证,但这不是一个好习惯。构造函数应仅用于初始化对象的状态/字段。您应该将其他事情的责任委托给其他方法。 请注意,构造函数仅被调用一次,即,只要您创建具有足够大输入量的新对象,就会在构造函数中引起异常。 这是为什么不应该使用构造函数包含“业务逻辑”的几个原因之一。