<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### [泛化的`Class`引用](https://lingcoder.gitee.io/onjava8/#/book/19-Type-Information?id=%e6%b3%9b%e5%8c%96%e7%9a%84-class-%e5%bc%95%e7%94%a8) `Class`引用總是指向某個`Class`對象,而`Class`對象可以用于產生類的實例,并且包含可作用于這些實例的所有方法代碼。它還包含該類的`static`成員,因此`Class`引用表明了它所指向對象的確切類型,而該對象便是`Class`類的一個對象。 但是,Java 設計者看準機會,將它的類型變得更具體了一些。Java 引入泛型語法之后,我們可以使用泛型對`Class`引用所指向的`Class`對象的類型進行限定。在下面的實例中,兩種語法都是正確的: ~~~ // typeinfo/GenericClassReferences.java public class GenericClassReferences { public static void main(String[] args) { Class intClass = int.class; Class<Integer> genericIntClass = int.class; genericIntClass = Integer.class; // 同一個東西 intClass = double.class; // genericIntClass = double.class; // 非法 } } ~~~ 普通的類引用不會產生警告信息。你可以看到,普通的類引用可以重新賦值指向任何其他的`Class`對象,但是使用泛型限定的類引用只能指向其聲明的類型。通過使用泛型語法,我們可以讓編譯器強制執行額外的類型檢查。 那如果我們希望稍微放松一些限制,應該怎么辦呢?乍一看,下面的操作好像是可以的: ~~~ Class<Number> geenericNumberClass = int.class; ~~~ 這看起來似乎是起作用的,因為`Integer`繼承自`Number`。但事實卻是不行,因為`Integer`的`Class`對象并不是`Number`的`Class`對象的子類(這看起來可能有點詭異,我們將在[泛型](https://lingcoder.gitee.io/onjava8/#/./20-Generics)這一章詳細討論)。 為了在使用`Class`引用時放松限制,我們使用了通配符,它是 Java 泛型中的一部分。通配符就是`?`,表示“任何事物”。因此,我們可以在上例的普通`Class`引用中添加通配符,并產生相同的結果: ~~~ // typeinfo/WildcardClassReferences.java public class WildcardClassReferences { public static void main(String[] args) { Class<?> intClass = int.class; intClass = double.class; } } ~~~ 使用`Class<?>`比單純使用`Class`要好,雖然它們是等價的,并且單純使用`Class`不會產生編譯器警告信息。使用`Class<?>`的好處是它表示你并非是碰巧或者由于疏忽才使用了一個非具體的類引用,而是特意為之。 為了創建一個限定指向某種類型或其子類的`Class`引用,我們需要將通配符與`extends`關鍵字配合使用,創建一個范圍限定。這與僅僅聲明`Class<Number>`不同,現在做如下聲明: ~~~ // typeinfo/BoundedClassReferences.java public class BoundedClassReferences { public static void main(String[] args) { Class<? extends Number> bounded = int.class; bounded = double.class; bounded = Number.class; // Or anything else derived from Number. } } ~~~ 向`Class`引用添加泛型語法的原因只是為了提供編譯期類型檢查,因此如果你操作有誤,稍后就會發現這點。使用普通的`Class`引用你要確保自己不會犯錯,因為一旦你犯了錯誤,就要等到運行時才能發現它,很不方便。 下面的示例使用了泛型語法,它保存了一個類引用,稍后又用`newInstance()`方法產生類的對象: ~~~ // typeinfo/DynamicSupplier.java import java.util.function.*; import java.util.stream.*; class CountedInteger { private static long counter; private final long id = counter++; @Override public String toString() { return Long.toString(id); } } public class DynamicSupplier<T> implements Supplier<T> { private Class<T> type; public DynamicSupplier(Class<T> type) { this.type = type; } public T get() { try { return type.newInstance(); } catch(InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } public static void main(String[] args) { Stream.generate( new DynamicSupplier<>(CountedInteger.class)) .skip(10) .limit(5) .forEach(System.out::println); } } ~~~ 輸出結果: ~~~ 10 11 12 13 14 ~~~ 注意,這個類必須假設與它一起工作的任何類型都有一個無參構造器,否則運行時會拋出異常。編譯期對該程序不會產生任何警告信息。 當你將泛型語法用于`Class`對象時,`newInstance()`將返回該對象的確切類型,而不僅僅只是在`ToyTest.java`中看到的基類`Object`。然而,這在某種程度上有些受限: ~~~ // typeinfo/toys/GenericToyTest.java // 測試 Class 類 // {java typeinfo.toys.GenericToyTest} package typeinfo.toys; public class GenericToyTest { public static void main(String[] args) throws Exception { Class<FancyToy> ftClass = FancyToy.class; // Produces exact type: FancyToy fancyToy = ftClass.newInstance(); Class<? super FancyToy> up = ftClass.getSuperclass(); // This won't compile: // Class<Toy> up2 = ftClass.getSuperclass(); // Only produces Object: Object obj = up.newInstance(); } } ~~~ 如果你手頭的是超類,那編譯器將只允許你聲明超類引用為“某個類,它是`FancyToy`的超類”,就像在表達式`Class<? super FancyToy>`中所看到的那樣。而不會接收`Class<Toy>`這樣的聲明。這看上去顯得有些怪,因為`getSuperClass()`方法返回的是基類(不是接口),并且編譯器在編譯期就知道它是什么類型了(在本例中就是`Toy.class`),而不僅僅只是"某個類"。不管怎樣,正是由于這種含糊性,`up.newInstance`的返回值不是精確類型,而只是`Object`。
                  <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>

                              哎呀哎呀视频在线观看