![](/img/trans.png)
[英]Java constructor with large arguments or Java bean getter/setter approach
[英]Java :Setter Getter and constructor
我對使用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 / setter來保證安全性,以及以后它們也可以用來更改或編輯值 。
我的問題是,如果構造函數是初始化點並且始終存在默認構造函數,為什么使用帶參數的構造函數來初始化值而不是getters / setter? 。 不會使用getter和setter提供安全性,並且能夠在任何階段輕松更改值。 請為我澄清這一點。
默認構造函數總是在那里
實際上它並不總是存在。 默認構造函數是由編譯器提供的構造函數(當然它是一個無參數構造函數) 只有在類中沒有定義其他構造函數的情況下
為什么我們使用帶參數的構造函數初始化值而不是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
才能創建author
。
new Book()
因為缺少no-arg構造函數,並且編譯器不會提供一個,因為已經定義了一個構造函數。 new Book()
因為我們的條件不符合,因為每本書都需要一個標題和作者。 這是參數化構造函數有用的條件。
有時,在創建類的新對象時,必須提供一些值。 例如,當連接到數據庫並創建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);
第一個看起來更好,對吧?
我的問題是,如果構造函數是初始化點,默認構造函數總是存在,那么為什么我們使用帶參數的構造函數來初始化值而不是set get。
如果你考慮一個對象轉換到不同的狀態,那么有一個參數化的構造函數以及setter和getter是有意義的。 讓我嘗試一個現實生活場景:想想一個Employee類,一個新員工加入,你不知道很多細節,但很少,你創建了Employee的對象,其屬性的defualt和基值。 您需要在系統中注冊員工,因此您使用了參數化構造函數。 獲得有關員工的更多詳細信息后,可以使用getter和setter來更新屬性。
這純粹取決於你的編碼風格。 但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");
雖然您可以在第一種情況下設置用戶名后立即發送登錄對象,但在收到結束時它將無效。 但第二種方法不容易出現錯誤,bcz必須傳遞所有必需的參數。
只是為了讓它更容易。 使用構造函數所需的代碼少於創建對象和使用setter所需的代碼。
有時,您無需在創建時將所有字段設置為特定值。 例如,當你制作一個數組時。 另外,如前所述,使用getter時更安全 - 你無法獲得nullpointer。
在使用參數定義構造函數時,請記住編寫默認構造函數。 或者一定不要使用它。
首先,兩種方法:構造函數和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");
}
}
通過構造函數初始化對象變量以避免nullpointers更容易,更安全。
如果在不初始化變量的情況下實例化對象並對其中一個空變量執行get操作,則可能會在運行時獲得nullpointer異常,因為您忘記手動設置其值。
另一方面,如果您總是在默認構造函數中初始化對象變量,那么在運行時期間獲得nullpointer異常的風險會大大降低,因為除非您通過setter(不是設置器)專門設置它們,否則您的所有變量都不能為null推薦的)。
帶參數的構造函數使您可以獲得完全構造的對象。 如果要使用默認值,則必須確保使用setter設置字段。 在設置某個屬性期間,假設拋出異常,現在您有一個不可用的對象。 在某些情況下,setter不會暴露,而是吸氣劑。 在這些情況下,使用帶有參數的構造函數或命名構造函數是正確的選項。 簡而言之,getter和setter確實有自己的重要性,而不是初始化對象。
因為在構造函數中將值設置為參數時,使用更少,更優雅和更易讀的代碼來編寫它。 此外,有時某些字段對於對象是必不可少的,因此參數構造函數會阻止用戶創建一個對象,省略對象功能的必要字段。 一個人雖然沒有“喋喋不休”地打電話給二傳手。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.