简体   繁体   English

有人可以向我解释这个方法签名吗

[英]Can someone explain to me this method signature

I am looking at the following code (someone else's code) and part of the code seems obscure to me:我正在查看以下代码(其他人的代码),部分代码对我来说似乎很模糊:

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

This part is straightforward, a ForkJoinPool.invokeAll() returning a List of Future objects and further processing returns a List of Strings.这部分很简单,一个 ForkJoinPool.invokeAll() 返回一个未来对象列表,进一步处理返回一个字符串列表。

Later, the list.stream().map() uses a static method on Mutil class Mutil.rethrowFunction(Future::get) and passes it an object of Future type.稍后,list.stream().map() 在 Mutil class Mutil.rethrowFunction(Future::get) 上使用 static 方法,并将其传递给 Future 类型的 ZA8CFDE6331BD59EB2AC96F8911C4B66。 Looking at the Mutil source code:查看 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: Here are my questions, as I am learning Generics, lambda and java.util.function package:
  1. The signature of Mutil.rethrowFunction() , says it returns <T, R> Function<T, R> and uses a parameter of type WithExceptionsIF<T, R> (which is a functional interface). Mutil.rethrowFunction()的签名表示它返回<T, R> Function<T, R>并使用类型为WithExceptionsIF<T, R>的参数(这是一个功能接口)。 How does Future.get() translates into the Mutil.rethroFunction() signature? Future.get() 如何转换为Mutil.rethroFunction()签名? Future.get(), returns a computed result and not a Function? Future.get(),返回计算结果而不是 Function?

  2. How does Future.get() , which is passed to Mutil.rethrowFunction() translates to WithExceptionIF<T,R> type?传递给Mutil.rethrowFunction() Future.get() Future.get() 如何转换为WithExceptionIF<T,R>类型?

  3. t->{return function.apply(t);} what is going on in this statement? t->{return function.apply(t);}这个语句是怎么回事? is 't' the Future object, if so then who is the "function"?不是未来 object,如果是,那么“功能”是谁?

  4. The signature of Mutil.throwAsUnchecked(Exception exception) method has <E extends Throwable> defined after the keyword "static". Mutil.throwAsUnchecked(Exception exception)方法的签名在关键字“static”之后定义了<E extends Throwable> If "exception" is the only parameter passed to the method, where does the E come from and why is it declared before the method's return type (void)?如果“异常”是传递给方法的唯一参数,那么 E 来自哪里,为什么在方法的返回类型(void)之前声明它?

Thanks for any clarity.感谢您的澄清。

Here's a complete runnable example.这是一个完整的可运行示例。

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. The get() method doesn't execute when rethrowFunction is called.调用rethrowFunction时不会执行get()方法。 The call to rethrowFunction just transforms the function passed in from one which throws a checked exception to one which doesn't (because any exception inwrapped in an unchecked exception).rethrowFunction的调用只是将传入的 function 从一个引发检查异常的一个转换为一个不引发检查的异常(因为任何异常都包含在未经检查的异常中)。 The collect() method actually calls the function, once for each Future in the Stream. collect()方法实际上调用了 function,为 Stream 中的每个Future调用一次。

  2. Think about passing Future::get using a lambda rather than a method reference.考虑使用 lambda 而不是方法引用传递Future::get It would be f -> f.get() .这将是f -> f.get() because we are passing a member function it takes the object it belongs to as a parameter.因为我们传递了一个成员 function ,所以它将它所属的 object 作为参数。 SO we are passing a function, and as the signature of get() is V get() throws InterruptedException, ExecutionException it matches WithExceptionsIF .所以我们传递了一个 function,并且由于 get() 的签名是V get() throws InterruptedException, ExecutionException它匹配WithExceptionsIF In fact it is an instance of WithExceptionsIF<Future,String> in this particular case.实际上,在这种特殊情况下,它是WithExceptionsIF<Future,String>的一个实例。

  3. If you expand this by substituting the lambda above, you get: return (f -> f.get()).apply(t) so get is being applied to the parameter being passed when the function which rethrowFunction` returns is evaluated.如果你通过替换上面的 lambda 来扩展它,你会得到: return (f -> f.get()).apply(t)所以当评估 rethrowFunction` 返回get is being applied to the parameter being passed when the function which

  4. This is explained here A peculiar feature of exception type inference in Java 8 Java is performing 'type inference'.此处解释了这一点Java 8 Java 中异常类型推断的特殊功能正在执行“类型推断”。 The compiler has been told that throwAsUnchecked throws an object whose class is a subclass of Throwable.编译器被告知throwAsUnchecked会抛出 object ,其 class 是 Throwable 的子类。 Because the return type of rethrowFunction does not declare a checked exception, the compiler decides that throwAsUnchecked must be throwing a RuntimeException .因为rethrowFunction的返回类型没有声明检查异常,所以编译器决定throwAsUnchecked必须抛出RuntimeException Another way of looking at it is that the type parameter in this case has its value inferred from the context the function is invoked in, rather than from its parameters.另一种看待它的方式是,在这种情况下,类型参数的值是从调用 function 的上下文中推断出来的,而不是从其参数中推断出来的。 At least I think that's how it works, it is not that easy to understand!至少我认为它是这样工作的,不是那么容易理解的!

Explaining that generic syntax more generally, often a method is part of a parameterised type, eg List<A> , so the type parameter can appear in the signature of member functions, eg A get(int i) .更一般地解释通用语法,通常方法是参数化类型的一部分,例如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. 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.

The get() method doesn't execute when rethrowFunction is called …“ get()方法在调用 rethrowFunction 时不执行……“

That's incorrect.这是不正确的。 Future::get is too called in rethrowFunction()s call chain; Future::getrethrowFunction()s调用链中被调用过; as a side effect of rethrowFunction() being called.作为调用rethrowFunction()的副作用。 The return type of Future::get is a MUtil.WithExceptionsIF . Future::get的返回类型是MUtil.WithExceptionsIF It is that return value that is passed as the input argument to rethrowFunction() .它是作为输入参数传递给rethrowFunction()的返回值。

That just transforms the function passed in from one which throws a checked exception to one which doesn't… 这只是将传入的 function 从一个引发检查异常的一个转换为一个不...

The wording of this sentence is confusing.这句话的措辞令人困惑。 It reads as if the „ That “ in the sentence refers to the Future::get .读起来好像句子中的“那个”指的是Future::get The get() method doesn't do that transform . get()方法不执行该转换 The rethrowFunction() method is what does the heavy lifting. rethrowFunction()方法是繁重的工作。

Think about passing Future::get…because we are passing a member function it takes the object it belongs to as a parameter 考虑传递 Future::get ......因为我们正在传递一个成员 function 它需要它所属的 object 作为参数

Future.get() doesn't take any parameters . Future.get()不带任何参数

…as the signature of get() is V get() throws InterruptedException, ExecutionException it matches WithExceptionsIF in this particular case …“ ...因为 get() 的签名是V get() throws InterruptedException, ExecutionException在这种特殊情况下匹配WithExceptionsIF ...“

This is not correct either.这也不对。 The signature of Future.get() has nothing to do with anything. Future.get()的签名与任何事情无关。 It's certainly not true that the signature of Future.get() matches WithExceptionsIF . Future.get()的签名与 WithExceptionsIF WithExceptionsIF肯定不是真的。 Again, the return type of Future.get() would be WithExceptionsIF in this particular invocation.同样,在此特定调用中, Future.get()返回类型将是WithExceptionsIF But a method's return type is not part of its signature .但是方法的返回类型不是其签名的一部分

Future.get() translates to * WithExceptionsIF<T,R> because forkJoinPool.invokeAll(tasks) returns a List<Future <MUtil.WithExceptionsIF<T,R>>> . Future.get()转换为 * WithExceptionsIF<T,R>因为forkJoinPool.invokeAll(tasks)返回一个List<Future <MUtil.WithExceptionsIF<T,R>>>

If you expand this by substituting the lambda above, you get: return (f -> f.get()).apply(t) so get is being applied to the parameter being passed when the function which rethrowFunction` returns is evaluated. 如果你通过替换上面的 lambda 来扩展它,你会得到: return (f -> f.get()).apply(t)所以get is being applied to the parameter being passed when the function which

Incorrect.不正确。 Again, Future.get() has nothing to do with it.同样, Future.get()与它无关。 Future.get()s job was done after it passed the WithExceptionsIF into rethrowFunction . Future.get()s工作在将 WithExceptionsIF 传递给WithExceptionsIFrethrowFunction The t -> {...} block defines a lambda which is returned by the call to rethrowFunction() . t -> {...}块定义了一个 lambda ,由rethrowFunction()调用返回。 The t is the input argument to the lambda. t是 lambda 的输入参数。 Its type will be of whatever type the type parameter T gets instantiated as.它的类型将是类型参数T实例化的任何类型。

Some concrete implementation of the WithExceptionsIF.apply() method is what would be called when that lambda is actually invoked;当实际调用 lambda 时,会调用WithExceptionsIF.apply()方法的一些具体实现; at some unknown later point.在后来的某个未知点。

The function we see there is an instance of WithExceptionsIF<T, R> passed in to rethrowFunction(WithExceptionsIF<T, R> function) . function我们看到有一个WithExceptionsIF<T, R>实例传入rethrowFunction(WithExceptionsIF<T, R> function)

…If "exception" is the only parameter passed to the method, where does the E come from and why is it declared before the method's return type (void)? …如果“异常”是传递给方法的唯一参数,那么 E 来自哪里,为什么要在方法的返回类型 (void) 之前声明它?

This: static <E extends Throwable> void throwAsUnchecked(Exception exception) is how generic methods are declared .这: static <E extends Throwable> void throwAsUnchecked(Exception exception)声明泛型方法的方式 The E type variable declared in the type parameter section is used in the method's throws clause.在类型参数部分中声明的E类型变量用于方法的throws子句。 Also in its body;也在它的身体里; to cast the Exception that's passed in to the method, to be of another, more specific type that would be specified at the point the generic method is actually invoked.将传递给方法的Exception转换为另一种更具体的类型,该类型将在实际调用泛型方法时指定。

Last, but not least: the List<string>... assignment is wrong for a couple reasons.最后但并非最不重要的一点是: List<string>...分配错误有几个原因。 The main reason is the stream in your example does not produce Stream<String> .主要原因是您示例中的 stream 不产生Stream<String> It produces Stream<Function<T, R>> .它产生Stream<Function<T, R>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM