[英]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; }
}
Mutil.rethrowFunction()
的簽名表示它返回<T, R> Function<T, R>
並使用類型為WithExceptionsIF<T, R>
的參數(這是一個功能接口)。 Future.get() 如何轉換為Mutil.rethroFunction()
簽名? Future.get(),返回計算結果而不是 Function?
傳遞給Mutil.rethrowFunction()
Future.get()
Future.get() 如何轉換為WithExceptionIF<T,R>
類型?
t->{return function.apply(t);}
這個語句是怎么回事? 不是未來 object,如果是,那么“功能”是誰?
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; }
}
調用rethrowFunction
時不會執行get()
方法。 對rethrowFunction
的調用只是將傳入的 function 從一個引發檢查異常的一個轉換為一個不引發檢查的異常(因為任何異常都包含在未經檢查的異常中)。 collect()
方法實際上調用了 function,為 Stream 中的每個Future
調用一次。
考慮使用 lambda 而不是方法引用傳遞Future::get
。 這將是f -> f.get()
。 因為我們傳遞了一個成員 function ,所以它將它所屬的 object 作為參數。 所以我們傳遞了一個 function,並且由於 get() 的簽名是V get() throws InterruptedException, ExecutionException
它匹配WithExceptionsIF
。 實際上,在這種特殊情況下,它是WithExceptionsIF<Future,String>
的一個實例。
如果你通過替換上面的 lambda 來擴展它,你會得到: return (f -> f.get()).apply(t)
所以當評估 rethrowFunction` 返回get is being applied to the parameter being passed when the function which
。
此處解釋了這一點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::get
在rethrowFunction()s
調用鏈中被調用過; 作為調用rethrowFunction()
的副作用。 Future::get
的返回類型是MUtil.WithExceptionsIF
。 它是作為輸入參數傳遞給rethrowFunction()
的返回值。
„這只是將傳入的 function 從一個引發檢查異常的一個轉換為一個不... “
這句話的措辭令人困惑。 讀起來好像句子中的“那個”指的是Future::get
。 get()
方法不執行該轉換。 rethrowFunction()
方法是繁重的工作。
„考慮傳遞 Future::get ......因為我們正在傳遞一個成員 function 它需要它所屬的 object 作為參數“
„ ...因為 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 傳遞給WithExceptionsIF
后rethrowFunction
。 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.