这个问题是关于lambda表达式似乎使用的Java包的明显"隐藏"或本地导入.
以下示例代码编译并运行正常(它只列出给定目录中的文件):
package com.mbm.stockbot;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Temp2 {
public static void main(String[] args) {
Temp2 t = new Temp2();
t.readDir();
}
public void readDir() {
try {
Files.walk(Paths.get("C:/Users/mbmas_000/Downloads/SEC Edgar"), 1).forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
System.out.println(filePath);
}
});
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,该变量filePath
是一个实例Path
,我认为它的实现包含在包中java.nio.file.Path
,尽管import
该包没有.
现在,如果我做了一个小修改,可以通过重构System.out.println
对它自己的方法的调用来说:
package com.mbm.stockbot;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Temp2 {
public static void main(String[] args) {
Temp2 t = new Temp2();
t.readDir();
}
public void readDir() {
try {
Files.walk(Paths.get("C:/Users/mbmas_000/Downloads/SEC Edgar"), 1).forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
printPath(filePath);
}
});
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void printPath(Path passedFilePath) {
System.out.println(passedFilePath);
}
}
Run Code Online (Sandbox Code Playgroud)
我现在必须'导入' import java.nio.file.Path
,否则我会收到编译器错误.
所以我的问题是:
如果filePath
的确是一个实例java.nio.file.Path
,为什么不要我需要导入它在第一个例子,和
如果使用lambda表达式执行进口"在幕后,"那么为什么你我需要添加import
,当我创建需要的实例的方法Path
作为参数?
可用的方法,以在两个呼叫filePath
和passedFilePath
是相同的,导致我相信他们的两个实例java.nio.file.Path
.
import
声明并不意味着声明您的代码正在使用哪些类; 他们只是声明用于解析非限定标识符的内容.因此,如果您Path
在代码中使用非限定标识符,则必须使用import java.nio.file.Path;
它来声明它应该被解析为此限定类型.顺便说一下,这不是解决名称的唯一方法.名称也可以通过类继承来解析,例如,如果它们与继承的成员类的简单名称匹配.
如果您在不引用其名称的情况下隐式使用类型,则不需要import
语句,这不仅限于lambda表达式,它甚至不是特殊的Java 8功能.例如
Files.walk(Paths.get("C:/Users/mbmas_000/Downloads/SEC Edgar"), 1)
Run Code Online (Sandbox Code Playgroud)
你已经Path
隐式使用了这个类型,因为它是返回类型Paths.get
和参数类型Files.walk
,换句话说,你正在接收一个实例java.nio.file.Path
并将其传递给另一个方法而不引用它的类型名称,因此你不需要import
.此外,您正在调用接受任意数量FileVisitOption
实例的varargs方法.您没有指定任何内容,因此您的代码将创建一个零长度FileVisitOption[]
数组并Files.walk
再次将其传递给没有import
.
使用改进的类型推断,还有另一种可能使用类型而不引用其名称,例如,如果您调用:
Files.newByteChannel(path, new HashSet<>());
Run Code Online (Sandbox Code Playgroud)
您不仅FileAttribute[]
要为varargs参数创建零长度数组而不通过名称引用此类型,还要创建一个HashSet<OpenOption>
不引用类型OpenOption
的名称.所以这也不需要,java.nio.file.attribute.FileAttribute
也不需要java.nio.file.OpenOption
.
所以最重要的是,你是否需要一个import
不依赖于类型的使用,而是你是否通过它的简单名称来引用它(并且有多种方法可以使用类型而不是通过名称引用它).在第二个示例中,您指的是Path
方法中的名称printPath(Path passedFilePath)
; 如果你改成它printPath(Object passedFilePath)
,一切都会在没有明确import
的情况下再次发挥作用java.nio.file.Path
.
归档时间: |
|
查看次数: |
439 次 |
最近记录: |