簡體   English   中英

Java:Setter Getter和構造函數

[英]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 
}

考慮一種情況,即只有具有titleauthor才能創建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,我會使用參數化構造函數:

  1. 初始化那些不應該更改的值。 (如person對象的username參數)

  2. 要初始化這些值,而不設置哪個,對象將處於無效狀態。

比如說,您正在向方法發送登錄參數。 你可以在這些方面使用

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是更改對象屬性的安全方法。 期望從類作者公開或不安全的方式來修改實例。

  1. 如果您還沒有編寫默認構造函數,則始終提供默認構造函數:

     // 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確實有自己的重要性,而不是初始化對象。

為什么要使用getter和setter?

因為在構造函數中將值設置為參數時,使用更少,更優雅和更易讀的代碼來編寫它。 此外,有時某些字段對於對象是必不可少的,因此參數構造函數會阻止用戶創建一個對象,省略對象功能的必要字段。 一個人雖然沒有“喋喋不休”地打電話給二傳手。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM