Java 8 - 静态方法参考规则

时间:2017-08-14 23:25:47

标签: java-8

我有以下代码:

public class Chap20 {

    public static void main(String[] args) {
        String[] names = { "John", "Jane" };
        Stream<String> namesStream = Stream.of(names);

        Path path = Paths.get(".");
        Stream<Path> files;
        try {
            files = Files.list(path);
            files.forEach(System.out::println);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

现在这里是file.forEach方法签名:

void java.util.stream.Stream.forEach(Consumer<? super Path> action)

我正在读取它作为一种接受类型的消费者的方法,该类型至少是Path类型或Path的超类,但我可能会错过它,因为System.out不是Path的超类。

有人可以解释一下如何正确阅读吗?

3 个答案:

答案 0 :(得分:2)

? super Path说:&#39;它必须是Path的超级类。

System.out.println接受ObjectObjectPath的超类,因此这是正确的。

答案 1 :(得分:2)

您正在阅读完全正确的IMO,您可能会被Sub test() Dim rng As Range Dim rngVals As Variant Set rng = YourSheet.ListObjects("Table2").Range rngVals = rng.Value YourSheet.ListObjects("Table2").Delete rng.Value = rngVals Set rng = Nothing End Sub 符号误导。这不是关于::System.out还是关于暗示参数Path(例如)你的问题因为方法参考而无法看到(进一步阅读)。

这里有几件事,第一件叫PECS;这就是宣言为x? super P_OUT的原因。基本上这意味着你可以阅读任何超级类型的? super Path。唯一安全的是Path(或任何子类型,但你不知道究竟是哪一个)。

为了简单起见,你可以这样编写它,例如:

Object

或者因为编译器可以看到(推断)类型为Stream.of("John", "Jane") .forEach((Object x) -> System.out.println(x)); // Object

String

或者你可以省略该声明,让编译器完成它的工作:

Stream.of("John", "Jane")
            .forEach((String x) -> System.out.println(x));  // String

现在第二部分称为Method Reference

而不是写作:

Stream.of("John", "Jane")
            .forEach(/* this is infered as String here */ x -> System.out.println(x));

你可以写得更简单:

 Stream.of("John", "Jane")
            .forEach(x -> System.out.println(x));

此处隐含 Stream.of("John", "Jane") .forEach(System.out::println); 参数(类型为x)。

答案 2 :(得分:1)

方法签名表示forEachStream方法接受一个Consumer,它消耗它迭代的Stream中的每个元素,在你的情况下是一个Paths集合。

Consumer指的是functional interface,它接受​​输入并且不返回任何结果。它是Java 8中实现的many之一,可与Lambdasmethod references一起使用。功能接口只包含一个抽象方法,也称为功能方法

forEach 方法用于迭代集合并对每个元素应用操作。传递的操作或“行为”(实现Consumer接口的任何类)是对集合的每个元素执行的 action 或lambda。

forEachIterable接口中的API(也添加了Java 8),“为Iterable的每个元素执行给定的操作,直到所有元素都被处理或该操作会抛出异常“。它与Java for loop 的不同之处在于它是一个内部迭代器,而不是外部迭代器。