<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 總結:類型轉換真的如此之糟嗎? 自從 C++ 模版出現以來,我就一直在致力于解釋它,我可能比大多數人都更早地提出了下面的論點。直到最近,我才停下來,去思考這個論點到底在多少時間內是有效的——我將要描述的問題到底有多少次可以穿越障礙得以解決。 這個論點就是:使用泛型類型機制的最吸引人的地方,就是在使用集合類的地方,這些類包括諸如各種 **List** 、各種 **Set** 、各種 **Map** 等你在 [集合](book/12-Collections.md) 和 [附錄:集合主題](book/Appendix-Collection-Topics.md) 這兩章所見。在 Java 5 之前,當你將一個對象放置到集合中時,這個對象就會被向上轉型為 **Object** ,因此你會丟失類型信息。當你想要將這個對象從集合中取回,用它去執行某些操作時,必須將其向下轉型回正確的類型。我用的示例是持有 **Cat** 的 **List** (這個示例的一種使用蘋果和桔子的變體在 [集合](book/12-Collections.md) 章節的開頭展示過)。如果沒有 Java 5 泛型版本的集合,你放到容集里和從集合中取回的都是 **Object** 。因此,我們很可能會將一個 **Dog** 放置到 **Cat** 的 **List** 中。 但是,泛型出現之前的 Java 并不會讓你誤用放入到集合中的對象。如果將一個 **Dog** 扔到 **Cat** 的集合中,并且試圖將這個集合中的所有東西都當作 **Cat** 處理,那么當你從這個 **Cat** 集合中取回那個 **Dog** 引用,并試圖將其轉型為 **Cat** 時,就會得到一個 **RuntimeException** 。你仍舊可以發現問題,但是是在運行時而非編譯期發現它的。 在本書以前的版本中,我曾經說過: > 這不止令人惱火,它還可能會產生難以發現的缺陷。如果這個程序的某個部分(或數個部分)向集合中插入了對象,并且通過異常,你在程序的另一個獨立的部分中發現有不良對象被放置到了集合中,那么必須發現這個不良插入到底是在何處發生的。 > 但是,隨著對這個論點的進一步檢查,我開始懷疑它了。首先,這會多么頻繁地發生呢?我記得這類事情從未發生在我身上,并且當我在會議上詢問其他人時,我也從來沒有聽說過有人碰上過。另一本書使用了一個稱為 **files** 的 list 示例,它包含 **String** 對象。在這個示例中,向 **files** 中添加一個 **File** 對象看起來相當自然,因此這個對象的名字可能叫 **fileNames** 更好。無論 Java 提供了多少類型檢查,仍舊可能會寫出晦澀的程序,而編寫差勁兒的程序即便可以編譯,它仍舊是編寫差勁兒的程序。可能大多數人都會使用命名良好的集合,例如 **cats** ,因為它們可以向試圖添加非 **Cat** 對象的程序員提供可視的警告。并且即便這類事情發生了,它真正又能潛伏多久呢?只要你開始用真實數據來運行測試,就會非常快地看到異常。 有一位作者甚至斷言,這樣的缺陷將“*潛伏數年*”。但是我不記得有任何大量的相關報告,來說明人們在查找“狗在貓列表中”這類缺陷時困難重重,或者是說明人們會非常頻繁地產生這種錯誤。然而,你將在 [多線程編程](book/24-Concurrent-Programming.md) 章節中看到,在使用線程時,出現那些可能看起來極罕見的缺陷,是很尋常并容易發生的事,而且,對于到底出了什么錯,這些缺陷只能給你一個很模糊的概念。因此,對于泛型是添加到 Java 中的非常顯著和相當復雜的特性這一點,“狗在貓列表中”這個論據真的能夠成為它的理由嗎? 我相信被稱為*泛型*的通用語言特性(并非必須是其在 Java 中的特定實現)的目的在于可表達性,而不僅僅是為了創建類型安全的集合。類型安全的集合是能夠創建更通用代碼這一能力所帶來的副作用。 因此,即便“狗在貓列表中”這個論據經常被用來證明泛型是必要的,但是它仍舊是有問題的。就像我在本章開頭聲稱的,我不相信這就是泛型這個概念真正的含義。相反,泛型正如其名稱所暗示的:它是一種方法,通過它可以編寫出更“泛化”的代碼,這些代碼對于它們能夠作用的類型具有更少的限制,因此單個的代碼段可以應用到更多的類型上。正如你在本章中看到的,編寫真正泛化的“持有器”類( Java 的容器就是這種類)相當簡單,但是編寫出能夠操作其泛型類型的泛化代碼就需要額外的努力了,這些努力需要類創建者和類消費者共同付出,他們必須理解這些代碼的概念和實現。這些額外的努力會增加使用這種特性的難度,并可能會因此而使其在某些場合缺乏可應用性,而在這些場合中,它可能會帶來附加的價值。 還要注意到,因為泛型是后來添加到 Java 中,而不是從一開始就設計到這種語言中的,所以某些容器無法達到它們應該具備的健壯性。例如,觀察一下 **Map** ,在特定的方法 `containsKey(Object key) `和 `get(Object key)` 中就包含這類情況。如果這些類是使用在它們之前就存在的泛型設計的,那么這些方法將會使用參數化類型而不是 **Object** ,因此也就可以提供這些泛型假設會提供的編譯期檢查。例如,在 C++ 的 **map** 中,鍵的類型總是在編譯期檢查的。 有一件事很明顯:在一種語言已經被廣泛應用之后,在其較新的版本中引入任何種類的泛型機制,都會是一項非常非常棘手的任務,并且是一項不付出艱辛就無法完成的任務。在 C++ 中,模版是在其最初的 ISO 版本中就引入的(即便如此,也引發了陣痛,因為在第一個標準 C++ 出現之前,有很多非模版版本在使用),因此實際上模版一直都是這種語言的一部分。在 Java 中,泛型是在這種語言首次發布大約 10 年之后才引入的,因此向泛型遷移的問題特別多,并且對泛型的設計產生了明顯的影響。其結果就是,程序員將承受這些痛苦,而這一切都是由于 Java 設計者在設計 1.0 版本時所表現出來的短視造成的。當 Java 最初被創建時,它的設計者們當然了解 C++ 的模版,他們甚至考慮將其囊括到 Java 語言中,但是出于這樣或那樣的原因,他們決定將模版排除在外(其跡象就是他們過于匆忙)。因此, Java 語言和使用它的程序員都將承受這些痛苦。只有時間將會說明 Java 的泛型方式對這種語言所造成的最終影響。 某些語言,已經融入了更簡潔、影響更小的方式,來實現參數化類型。我們不可能不去想象這樣的語言將會成為 Java 的繼任者,因為它們采用的方式,與 C++ 通過 C 來實現的方式相同:按原樣使用它,然后對其進行改進。
                  <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>

                              哎呀哎呀视频在线观看