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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## Java8 中的輔助潛在類型 先前聲明關于 Java 缺乏對潛在類型的支持在 Java 8 之前是完全正確的。但是,Java 8 中的非綁定方法引用使我們能夠產生一種潛在類型的形式,以滿足創建一段可工作在不相干類型上的代碼。因為 Java 最初并不是如此設計,所以結果可想而知,比其他語言中要尷尬一些。但是,至少現在成為了可能,只是缺乏令人驚艷之處。 我在其他地方從沒遇過這種技術,因此我將其稱為輔助潛在類型。 我們將重寫 **DogsAndRobots.java** 來演示該技術。 為使外觀看起來與原始示例盡可能相似,我僅向每個原始類名添加了 **A**: ```java // generics/DogsAndRobotMethodReferences.java // "Assisted Latent Typing" import typeinfo.pets.*; import java.util.function.*; class PerformingDogA extends Dog { public void speak() { System.out.println("Woof!"); } public void sit() { System.out.println("Sitting"); } public void reproduce() {} } class RobotA { public void speak() { System.out.println("Click!"); } public void sit() { System.out.println("Clank!"); } public void oilChange() {} } class CommunicateA { public static <P> void perform(P performer, Consumer<P> action1, Consumer<P> action2) { action1.accept(performer); action2.accept(performer); } } public class DogsAndRobotMethodReferences { public static void main(String[] args) { CommunicateA.perform(new PerformingDogA(), PerformingDogA::speak, PerformingDogA::sit); CommunicateA.perform(new RobotA(), RobotA::speak, RobotA::sit); CommunicateA.perform(new Mime(), Mime::walkAgainstTheWind, Mime::pushInvisibleWalls); } } /* Output: Woof! Sitting Click! Clank! */ ``` **PerformingDogA** 和 **RobotA** 與 **DogsAndRobots.java** 中的相同,不同之處在于它們不繼承通用接口 **Performs** ,因此它們沒有通用性。 `CommunicateA.perform()` 在沒有約束的 **P** 上生成。 只要可以使用 `Consumer <P>`,它在這里就可以是任何東西,這些 `Consumer<P>` 代表不帶參數的 **P** 方法的未綁定方法引用。當您調用 **Consumer** 的 `accept()` 方法時,它將方法引用綁定到執行者對象并調用該方法。 由于 [函數式編程](book/13-Functional-Programming.md) 一章中描述的“魔術”,我們可以將任何符合簽名的未綁定方法引用傳遞給 `CommunicateA.perform()` 。 之所以稱其為“輔助”,是因為您必須顯式地為 `perform()` 提供要使用的方法引用。 它不能只按名稱調用方法。 盡管傳遞未綁定的方法引用似乎要花很多力氣,但潛在類型的最終目標還是可以實現的。 我們創建了一個代碼片段 `CommunicateA.perform()` ,該代碼可用于任何具有符合簽名的方法引用的類型。 請注意,這與我們看到的其他語言中的潛在類型有所不同,因為這些語言不僅需要簽名以符合規范,還需要方法名稱。 因此,該技術可以說產生了更多的通用代碼。 為了證明這一點,我還從 **LatentReflection.java** 中引入了 **Mime**。 ### 使用**Suppliers**類的通用方法 通過輔助潛在類型,我們可以定義本章其他部分中使用的 **Suppliers** 類。 此類包含使用生成器填充 **Collection** 的工具方法。 泛化這些操作很有意義: ```java // onjava/Suppliers.java // A utility to use with Suppliers package onjava; import java.util.*; import java.util.function.*; import java.util.stream.*; public class Suppliers { // Create a collection and fill it: public static <T, C extends Collection<T>> C create(Supplier<C> factory, Supplier<T> gen, int n) { return Stream.generate(gen) .limit(n) .collect(factory, C::add, C::addAll); } // Fill an existing collection: public static <T, C extends Collection<T>> C fill(C coll, Supplier<T> gen, int n) { Stream.generate(gen) .limit(n) .forEach(coll::add); return coll; } // Use an unbound method reference to // produce a more general method: public static <H, A> H fill(H holder, BiConsumer<H, A> adder, Supplier<A> gen, int n) { Stream.generate(gen) .limit(n) .forEach(a -> adder.accept(holder, a)); return holder; } } ``` `create()` 為你創建一個新的 **Collection** 子類型,而 `fill()` 的第一個版本將元素放入 **Collection** 的現有子類型中。 請注意,還會返回傳入的容器的確切類型,因此不會丟失類型信息。 前兩種方法一般都受約束,只能與 **Collection** 子類型一起使用。`fill()` 的第二個版本適用于任何類型的 **holder** 。 它需要一個附加參數:未綁定方法引用 `adder. fill()` ,使用輔助潛在類型來使其與任何具有添加元素方法的 **holder** 類型一起使用。因為此未綁定方法 **adder** 必須帶有一個參數(要添加到 **holder** 的元素),所以 **adder** 必須是 `BiConsumer <H,A>` ,其中 **H** 是要綁定到的 **holder** 對象的類型,而 **A** 是要被添加的綁定元素類型。 對 `accept()` 的調用將使用參數 a 調用對象 **holder** 上的未綁定方法 **holder**。 在一個稍作模擬的測試中對 **Suppliers** 工具程序進行了測試,該仿真還使用了本章前面定義的 **RandomList** : ```java // generics/BankTeller.java // A very simple bank teller simulation import java.util.*; import onjava.*; class Customer { private static long counter = 1; private final long id = counter++; @Override public String toString() { return "Customer " + id; } } class Teller { private static long counter = 1; private final long id = counter++; @Override public String toString() { return "Teller " + id; } } class Bank { private List<BankTeller> tellers = new ArrayList<>(); public void put(BankTeller bt) { tellers.add(bt); } } public class BankTeller { public static void serve(Teller t, Customer c) { System.out.println(t + " serves " + c); } public static void main(String[] args) { // Demonstrate create(): RandomList<Teller> tellers = Suppliers.create( RandomList::new, Teller::new, 4); // Demonstrate fill(): List<Customer> customers = Suppliers.fill( new ArrayList<>(), Customer::new, 12); customers.forEach(c -> serve(tellers.select(), c)); // Demonstrate assisted latent typing: Bank bank = Suppliers.fill( new Bank(), Bank::put, BankTeller::new, 3); // Can also use second version of fill(): List<Customer> customers2 = Suppliers.fill( new ArrayList<>(), List::add, Customer::new, 12); } } /* Output: Teller 3 serves Customer 1 Teller 2 serves Customer 2 Teller 3 serves Customer 3 Teller 1 serves Customer 4 Teller 1 serves Customer 5 Teller 3 serves Customer 6 Teller 1 serves Customer 7 Teller 2 serves Customer 8 Teller 3 serves Customer 9 Teller 3 serves Customer 10 Teller 2 serves Customer 11 Teller 4 serves Customer 12 */ ``` 可以看到 `create()` 生成一個新的 **Collection** 對象,而 `fill()` 添加到現有 **Collection** 中。第二個版本`fill()` 顯示,它不僅與無關的新類型 **Bank** 一起使用,還能與 **List** 一起使用。因此,從技術上講,`fill()` 的第一個版本在技術上不是必需的,但在使用 **Collection** 時提供了較短的語法。
                  <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>

                              哎呀哎呀视频在线观看