<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 12.1 傳遞引用 將引用傳遞進入一個方法時,指向的仍然是相同的對象。一個簡單的實驗可以證明這一點(若執行這個程序時有麻煩,請參考第3章3.1.2小節“賦值”): ``` //: PassHandles.java // Passing handles around package c12; public class PassHandles { static void f(PassHandles h) { System.out.println("h inside f(): " + h); } public static void main(String[] args) { PassHandles p = new PassHandles(); System.out.println("p inside main(): " + p); f(p); } } ///:~ ``` `toString`方法會在打印語句里自動調用,而`PassHandles`直接從`Object`繼承,沒有`toString`的重新定義。因此,這里會采用`toString`的`Object`版本,打印出對象的類,接著是那個對象所在的位置(不是引用,而是對象的實際存儲位置)。輸出結果如下: ``` p inside main(): PassHandles@1653748 h inside f() : PassHandles@1653748 ``` 可以看到,無論`p`還是`h`引用的都是同一個對象。這比復制一個新的`PassHandles`對象有效多了,使我們能將一個參數發給一個方法。但這樣做也帶來了另一個重要的問題。 ## 12.1.1 別名問題 “別名”意味著多個引用都試圖指向同一個對象,就象前面的例子展示的那樣。若有人向那個對象里寫入一點什么東西,就會產生別名問題。若其他引用的所有者不希望那個對象改變,恐怕就要失望了。這可用下面這個簡單的例子說明: ``` //: Alias1.java // Aliasing two handles to one object public class Alias1 { int i; Alias1(int ii) { i = ii; } public static void main(String[] args) { Alias1 x = new Alias1(7); Alias1 y = x; // Assign the handle System.out.println("x: " + x.i); System.out.println("y: " + y.i); System.out.println("Incrementing x"); x.i++; System.out.println("x: " + x.i); System.out.println("y: " + y.i); } } ///:~ ``` 對下面這行: ``` Alias1 y = x; // Assign the handle ``` 它會新建一個`Alias1`引用,但不是把它分配給由new創建的一個新鮮對象,而是分配給一個現有的引用。所以引用x的內容——即對象`x`指向的地址——被分配給`y`,所以無論`x`還是`y`都與相同的對象連接起來。這樣一來,一旦`x`的`i`在下述語句中自增: ``` x.i++; ``` `y`的`i`值也必然受到影響。從最終的輸出就可以看出: ``` x: 7 y: 7 Incrementing x x: 8 y: 8 ``` 此時最直接的一個解決辦法就是干脆不這樣做:不要有意將多個引用指向同一個作用域內的同一個對象。這樣做可使代碼更易理解和調試。然而,一旦準備將引用作為一個變量或參數傳遞——這是Java設想的正常方法——別名問題就會自動出現,因為創建的本地引用可能修改“外部對象”(在方法作用域之外創建的對象)。下面是一個例子: ``` //: Alias2.java // Method calls implicitly alias their // arguments. public class Alias2 { int i; Alias2(int ii) { i = ii; } static void f(Alias2 handle) { handle.i++; } public static void main(String[] args) { Alias2 x = new Alias2(7); System.out.println("x: " + x.i); System.out.println("Calling f(x)"); f(x); System.out.println("x: " + x.i); } } ///:~ ``` 輸出如下: ``` x: 7 Calling f(x) x: 8 ``` 方法改變了自己的參數——外部對象。一旦遇到這種情況,必須判斷它是否合理,用戶是否愿意這樣,以及是不是會造成問題。 通常,我們調用一個方法是為了產生返回值,或者用它改變為其調用方法的那個對象的狀態(方法其實就是我們向那個對象“發一條消息”的方式)。很少需要調用一個方法來處理它的參數;這叫作利用方法的“副作用”(Side Effect)。所以倘若創建一個會修改自己參數的方法,必須向用戶明確地指出這一情況,并警告使用那個方法可能會有的后果以及它的潛在威脅。由于存在這些混淆和缺陷,所以應該盡量避免改變參數。 若需在一個方法調用期間修改一個參數,且不打算修改外部參數,就應在自己的方法內部制作一個副本,從而保護那個參數。本章的大多數內容都是圍繞這個問題展開的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看