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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## [泛型和類型安全的集合](https://lingcoder.gitee.io/onjava8/#/book/12-Collections?id=%e6%b3%9b%e5%9e%8b%e5%92%8c%e7%b1%bb%e5%9e%8b%e5%ae%89%e5%85%a8%e7%9a%84%e9%9b%86%e5%90%88) 使用 Java 5 之前的集合的一個主要問題是編譯器允許你向集合中插入不正確的類型。例如,考慮一個**Apple**對象的集合,這里使用最基本最可靠的**ArrayList**。現在,可以把**ArrayList**看作“可以自動擴充自身尺寸的數組”來看待。使用**ArrayList**相當簡單:創建一個實例,用`add()`插入對象;然后用`get()`來訪問這些對象,此時需要使用索引,就像數組那樣,但是不需要方括號。[^2](https://lingcoder.gitee.io/onjava8/#/%E8%BF%99%E9%87%8C%E6%98%AF%E6%93%8D%E4%BD%9C%E7%AC%A6%E9%87%8D%E8%BD%BD%E7%9A%84%E7%94%A8%E6%AD%A6%E4%B9%8B%E5%9C%B0%EF%BC%8CC++%E5%92%8CC?id=%e7%9a%84%e9%9b%86%e5%90%88%e7%b1%bb%e9%83%bd%e4%bd%bf%e7%94%a8%e6%93%8d%e4%bd%9c%e7%ac%a6%e9%87%8d%e8%bd%bd%e7%94%9f%e6%88%90%e4%ba%86%e6%9b%b4%e7%ae%80%e6%b4%81%e7%9a%84%e8%af%ad%e6%b3%95%e3%80%82)**ArrayList**還有一個`size()`方法,來說明集合中包含了多少個元素,所以不會不小心因數組越界而引發錯誤(通過拋出*運行時異常*,[異常](https://lingcoder.gitee.io/onjava8/#/)章節介紹了異常)。 在本例中,**Apple**和**Orange**都被放到了集合中,然后將它們取出。正常情況下,Java編譯器會給出警告,因為這個示例沒有使用泛型。在這里,使用特定的注解來抑制警告信息。注解以“@”符號開頭,可以帶參數。這里的`@SuppressWarning`注解及其參數表示只抑制“unchecked”類型的警告([注解](https://lingcoder.gitee.io/onjava8/#/)章節將介紹更多有關注解的信息): ~~~ // collections/ApplesAndOrangesWithoutGenerics.java // Simple collection use (suppressing compiler warnings) // {ThrowsException} import java.util.*; class Apple { private static long counter; private final long id = counter++; public long id() { return id; } } class Orange {} public class ApplesAndOrangesWithoutGenerics { @SuppressWarnings("unchecked") public static void main(String[] args) { ArrayList apples = new ArrayList(); for(int i = 0; i < 3; i++) apples.add(new Apple()); // No problem adding an Orange to apples: apples.add(new Orange()); for(Object apple : apples) { ((Apple) apple).id(); // Orange is detected only at run time } } } /* Output: ___[ Error Output ]___ Exception in thread "main" java.lang.ClassCastException: Orange cannot be cast to Apple at ApplesAndOrangesWithoutGenerics.main(ApplesA ndOrangesWithoutGenerics.java:23) */ ~~~ **Apple**和**Orange**是截然不同的,它們除了都是**Object**之外沒有任何共同點(如果一個類沒有顯式地聲明繼承自哪個類,那么它就自動繼承自**Object**)。因為**ArrayList**保存的是**Object**,所以不僅可以通過**ArrayList**的`add()`方法將**Apple**對象放入這個集合,而且可以放入**Orange**對象,這無論在編譯期還是運行時都不會有問題。當使用**ArrayList**的`get()`方法來取出你認為是**Apple**的對象時,得到的只是**Object**引用,必須將其轉型為**Apple**。然后需要將整個表達式用括號括起來,以便在調用**Apple**的`id()`方法之前,強制執行轉型。否則,將會產生語法錯誤。 在運行時,當嘗試將**Orange**對象轉為**Apple**時,會出現輸出中顯示的錯誤。 在[泛型](https://lingcoder.gitee.io/onjava8/#/)章節中,你將了解到使用 Java 泛型來創建類可能很復雜。但是,使用預先定義的泛型類卻相當簡單。例如,要定義一個用于保存**Apple**對象的**ArrayList**,只需要使用**ArrayList**來代替**ArrayList**。尖括號括起來的是*類型參數*(可能會有多個),它指定了這個集合實例可以保存的類型。 通過使用泛型,就可以在編譯期防止將錯誤類型的對象放置到集合中。[^3](https://lingcoder.gitee.io/onjava8/#/%E5%9C%A8[%E6%B3%9B%E5%9E%8B]()%E7%AB%A0%E8%8A%82%E7%9A%84%E6%9C%AB%E5%B0%BE%EF%BC%8C%E6%9C%89%E4%B8%AA%E5%85%B3%E4%BA%8E%E8%BF%99%E4%B8%AA%E9%97%AE%E9%A2%98%E6%98%AF%E5%90%A6%E5%BE%88%E4%B8%A5%E9%87%8D%E7%9A%84%E8%AE%A8%E8%AE%BA%E3%80%82%E4%BD%86%E6%98%AF%EF%BC%8C[%E6%B3%9B%E5%9E%8B]()%E7%AB%A0%E8%8A%82%E8%BF%98%E5%B0%86%E5%B1%95%E7%A4%BAJava%E6%B3%9B%E5%9E%8B%E8%BF%9C%E4%B8%8D%E6%AD%A2%E6%98%AF%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%E7%9A%84%E9%9B%86%E5%90%88%E8%BF%99%E4%B9%88%E7%AE%80%E5%8D%95%E3%80%82)下面還是這個示例,但是使用了泛型: ~~~ // collections/ApplesAndOrangesWithGenerics.java import java.util.*; public class ApplesAndOrangesWithGenerics { public static void main(String[] args) { ArrayList<Apple> apples = new ArrayList<>(); for(int i = 0; i < 3; i++) apples.add(new Apple()); // Compile-time error: // apples.add(new Orange()); for(Apple apple : apples) { System.out.println(apple.id()); } } } /* Output: 0 1 2 */ ~~~ 在**apples**定義的右側,可以看到`new ArrayList<>()`。這有時被稱為“菱形語法”(diamond syntax)。在 Java 7 之前,必須要在兩端都進行類型聲明,如下所示: ~~~ ArrayList<Apple> apples = new ArrayList<Apple>(); ~~~ 隨著類型變得越來越復雜,這種重復產生的代碼非常混亂且難以閱讀。程序員發現所有類型信息都可以從左側獲得,因此,編譯器沒有理由強迫右側再重復這些。雖然*類型推斷*(type inference)只是個很小的請求,Java 語言團隊仍然欣然接受并進行了改進。 有了**ArrayList**聲明中的類型指定,編譯器會阻止將**Orange**放入**apples**,因此,這會成為一個編譯期錯誤而不是運行時錯誤。 使用泛型,從**List**中獲取元素不需要強制類型轉換。因為**List**知道它持有什么類型,因此當調用`get()`時,它會替你執行轉型。因此,使用泛型,你不僅知道編譯器將檢查放入集合的對象類型,而且在使用集合中的對象時也可以獲得更清晰的語法。 當指定了某個類型為泛型參數時,并不僅限于只能將確切類型的對象放入集合中。向上轉型也可以像作用于其他類型一樣作用于泛型: ~~~ // collections/GenericsAndUpcasting.java import java.util.*; class GrannySmith extends Apple {} class Gala extends Apple {} class Fuji extends Apple {} class Braeburn extends Apple {} public class GenericsAndUpcasting { public static void main(String[] args) { ArrayList<Apple> apples = new ArrayList<>(); apples.add(new GrannySmith()); apples.add(new Gala()); apples.add(new Fuji()); apples.add(new Braeburn()); for(Apple apple : apples) System.out.println(apple); } } /* Output: GrannySmith@15db9742 Gala@6d06d69c Fuji@7852e922 Braeburn@4e25154f */ ~~~ 因此,可以將**Apple**的子類型添加到被指定為保存**Apple**對象的集合中。 程序的輸出是從**Object**默認的`toString()`方法產生的,該方法打印類名,后邊跟著對象的散列碼的無符號十六進制表示(這個散列碼是通過`hashCode()`方法產生的)。將在[附錄:理解equals和hashCode方法](https://lingcoder.gitee.io/onjava8/#/)中了解有關散列碼的內容。
                  <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>

                              哎呀哎呀视频在线观看