Java 8 Java8-静态方法引用规则

Java 8 Java8-静态方法引用规则,java-8,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> file

我有以下代码:

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();
        }
    }

}
公共类第20章{
公共静态void main(字符串[]args){
字符串[]名称={“John”,“Jane”};
Stream namesStream=Stream.of(名称);
路径路径=路径。获取(“.”);
流文件;
试一试{
files=files.list(路径);
files.forEach(System.out::println);
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
下面是file.forEach方法签名:

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

void java.util.stream.stream.forEach(Consumer
?super Path
说:“它必须是Path的超类


System.out.println
接受
对象
对象
路径
的一个超类,因此这是正确的。

方法签名表示接受使用者的方法,该使用者使用它所迭代的流中的每个元素,在您的情况下是路径的集合

指接受输入但不返回结果的。它是用Java 8实现的与和一起工作的方法之一。函数接口只包含一个抽象方法,也称为其函数方法

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


是接口中的一个API(也与Java 8一起添加),它“对Iterable的每个元素执行给定的操作,直到所有元素都已处理或该操作引发异常为止”它与Java for循环的不同之处在于它是一个内部迭代器,而不是一个外部迭代器。

你在读完全正确的IMO,你可能只是被
符号误导了。它与
系统无关。out
是否是
路径
有关-它与隐含参数
x
(例如)由于方法引用而无法看到(请进一步阅读)

这里有两个东西,第一个被调用;这就是为什么声明是
?super p_OUT
?super Path
。基本上,这意味着你可以读取任何超类型的
路径
。唯一安全的是
对象
(或者是它的任何子类型,但你不知道具体是哪一种)

为了简化,您可以这样编写,例如:

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
或者您可以完全忽略该声明,让编译器完成它的工作:

Stream.of("John", "Jane")
            .forEach(/* this is infered as String here */ x -> System.out.println(x));
现在第二部分被称为a

而不是写:

 Stream.of("John", "Jane")
            .forEach(x -> System.out.println(x));
你可以写得更简单一些:

 Stream.of("John", "Jane")
            .forEach(System.out::println);

x
参数(类型为
?super T
)这里暗示了。

嘿,你误读了OP的问题。答案很简单,因为任何东西都是
对象
,并且声明超级类型可以用它的子类型替换。方法引用表达式
System.out::println
将适应目标类型
消费者有几个重载的
println
.T编译器选择了最适用的一个。在这种情况下,就是接收
对象的对象
.ups!我的错,我认为它是
,但它是
,这是一个非常简洁的解释,让我意识到我考虑的是
系统.out
类型,而不是
系统.out.println
参数类型作为超级路径。谢谢。