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