簡體   English   中英

有人可以向我解釋這個方法簽名嗎

[英]Can someone explain to me this method signature

我正在查看以下代碼(其他人的代碼),部分代碼對我來說似乎很模糊:

List<string> result = forkJoinPool.invokeAll(tasks)
            .stream()
            .map(MUtil.rethrowFunction(Future::get))
            .collect(toList());

這部分很簡單,一個 ForkJoinPool.invokeAll() 返回一個未來對象列表,進一步處理返回一個字符串列表。

稍后,list.stream().map() 在 Mutil class Mutil.rethrowFunction(Future::get) 上使用 static 方法,並將其傳遞給 Future 類型的 ZA8CFDE6331BD59EB2AC96F8911C4B66。 查看 Mutil 源代碼:

public class Mutil {
    public static <T, R> Function<T, R> rethrowFunction(WithExceptionsIF<T, R> function) {
        return t -> {
            try { return function.apply(t); }
            catch (Exception exception) { throwAsUnchecked(exception); return null; }
        };
    }
    @FunctionalInterface
      public interface WithExceptionsIF<T, R> {
          R apply(T t) throws Exception;
    }

    @SuppressWarnings ("unchecked")
    private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E { throw (E)exception; }
}

Here are my questions, as I am learning Generics, lambda and java.util.function package:
  1. Mutil.rethrowFunction()的簽名表示它返回<T, R> Function<T, R>並使用類型為WithExceptionsIF<T, R>的參數(這是一個功能接口)。 Future.get() 如何轉換為Mutil.rethroFunction()簽名? Future.get(),返回計算結果而不是 Function?

  2. 傳遞給Mutil.rethrowFunction() Future.get() Future.get() 如何轉換為WithExceptionIF<T,R>類型?

  3. t->{return function.apply(t);}這個語句是怎么回事? 不是未來 object,如果是,那么“功能”是誰?

  4. Mutil.throwAsUnchecked(Exception exception)方法的簽名在關鍵字“static”之后定義了<E extends Throwable> 如果“異常”是傳遞給方法的唯一參數,那么 E 來自哪里,為什么在方法的返回類型(void)之前聲明它?

感謝您的澄清。

這是一個完整的可運行示例。

package org.example;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.function.Function;

import static java.util.stream.Collectors.toList;

public class SO62737345 {
    public static void main(String... args) {
        ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
        List<Callable<String>> tasks = Collections.singletonList(() -> "fish");
        List<String> result = forkJoinPool.invokeAll(tasks)
                .stream()
                .map(rethrowFunction(Future::get))
                .collect(toList());
    }

    public static <T, R> Function<T, R> rethrowFunction(WithExceptionsIF<T, R> function) {
        return t -> {
            try {
                return function.apply(t);
            }
            catch (Exception exception) { throwAsUnchecked(exception);  return null; }
        };
    }
    @FunctionalInterface
    public interface WithExceptionsIF<T, R> {
        R apply(T t) throws Exception;
    }

    @SuppressWarnings ("unchecked")
    private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E { throw (E)exception; }
}
  1. 調用rethrowFunction時不會執行get()方法。 rethrowFunction的調用只是將傳入的 function 從一個引發檢查異常的一個轉換為一個不引發檢查的異常(因為任何異常都包含在未經檢查的異常中)。 collect()方法實際上調用了 function,為 Stream 中的每個Future調用一次。

  2. 考慮使用 lambda 而不是方法引用傳遞Future::get 這將是f -> f.get() 因為我們傳遞了一個成員 function ,所以它將它所屬的 object 作為參數。 所以我們傳遞了一個 function,並且由於 get() 的簽名是V get() throws InterruptedException, ExecutionException它匹配WithExceptionsIF 實際上,在這種特殊情況下,它是WithExceptionsIF<Future,String>的一個實例。

  3. 如果你通過替換上面的 lambda 來擴展它,你會得到: return (f -> f.get()).apply(t)所以當評估 rethrowFunction` 返回get is being applied to the parameter being passed when the function which

  4. 此處解釋了這一點Java 8 Java 中異常類型推斷的特殊功能正在執行“類型推斷”。 編譯器被告知throwAsUnchecked會拋出 object ,其 class 是 Throwable 的子類。 因為rethrowFunction的返回類型沒有聲明檢查異常,所以編譯器決定throwAsUnchecked必須拋出RuntimeException 另一種看待它的方式是,在這種情況下,類型參數的值是從調用 function 的上下文中推斷出來的,而不是從其參數中推斷出來的。 至少我認為它是這樣工作的,不是那么容易理解的!

更一般地解釋通用語法,通常方法是參數化類型的一部分,例如List<A> ,因此類型參數可以出現在成員函數的簽名中,例如A get(int i) You can also have a generic function whose signature has type parameters which do not appear in the class (or a static function which is not associated with an instance of the class), and here they are declared before the return type.

get()方法在調用 rethrowFunction 時不執行……“

這是不正確的。 Future::getrethrowFunction()s調用鏈中被調用過; 作為調用rethrowFunction()的副作用。 Future::get的返回類型是MUtil.WithExceptionsIF 它是作為輸入參數傳遞給rethrowFunction()的返回值。

這只是將傳入的 function 從一個引發檢查異常的一個轉換為一個不...

這句話的措辭令人困惑。 讀起來好像句子中的“那個”指的是Future::get get()方法不執行該轉換 rethrowFunction()方法是繁重的工作。

考慮傳遞 Future::get ......因為我們正在傳遞一個成員 function 它需要它所屬的 object 作為參數

Future.get()不帶任何參數

...因為 get() 的簽名是V get() throws InterruptedException, ExecutionException在這種特殊情況下匹配WithExceptionsIF ...“

這也不對。 Future.get()的簽名與任何事情無關。 Future.get()的簽名與 WithExceptionsIF WithExceptionsIF肯定不是真的。 同樣,在此特定調用中, Future.get()返回類型將是WithExceptionsIF 但是方法的返回類型不是其簽名的一部分

Future.get()轉換為 * WithExceptionsIF<T,R>因為forkJoinPool.invokeAll(tasks)返回一個List<Future <MUtil.WithExceptionsIF<T,R>>>

如果你通過替換上面的 lambda 來擴展它,你會得到: return (f -> f.get()).apply(t)所以get is being applied to the parameter being passed when the function which

不正確。 同樣, Future.get()與它無關。 Future.get()s工作在將 WithExceptionsIF 傳遞給WithExceptionsIFrethrowFunction t -> {...}塊定義了一個 lambda ,由rethrowFunction()調用返回。 t是 lambda 的輸入參數。 它的類型將是類型參數T實例化的任何類型。

當實際調用 lambda 時,會調用WithExceptionsIF.apply()方法的一些具體實現; 在后來的某個未知點。

function我們看到有一個WithExceptionsIF<T, R>實例傳入rethrowFunction(WithExceptionsIF<T, R> function)

…如果“異常”是傳遞給方法的唯一參數,那么 E 來自哪里,為什么要在方法的返回類型 (void) 之前聲明它?

這: static <E extends Throwable> void throwAsUnchecked(Exception exception)聲明泛型方法的方式 在類型參數部分中聲明的E類型變量用於方法的throws子句。 也在它的身體里; 將傳遞給方法的Exception轉換為另一種更具體的類型,該類型將在實際調用泛型方法時指定。

最后但並非最不重要的一點是: List<string>...分配錯誤有幾個原因。 主要原因是您示例中的 stream 不產生Stream<String> 它產生Stream<Function<T, R>>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM