Java Lambda 表达式是否利用“隐藏"?或本地包进口? [英] Do Java Lambda Expressions Utilize "Hidden" or Local Package Imports?

查看:20
本文介绍了Java Lambda 表达式是否利用“隐藏"?或本地包进口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是关于 lambda 表达式似乎使用的 Java 包的明显隐藏"或本地导入.

This question is about the apparent "hidden" or local imports of Java packages that lambda expressions seem to employ.

以下示例代码编译并运行良好(它只列出给定目录中的文件):

The following sample code compiles and runs fine (it just lists the files in the given directory):

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

注意变量 filePathPath 的一个实例,我认为它的实现包含在包 java.nio.file.Path 中,尽管该包没有 import.

Note that the variable filePath is an instance of Path, whose implementation I think is contained in package java.nio.file.Path, although there is no import for that package.

现在,如果我做一个小的修改,比如将对 System.out.println 的调用重构为它自己的方法:

Now, if I make a small modification, say by refactoring the call to System.out.println to its own method:

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

我现在必须导入"import java.nio.file.Path,否则我会收到编译器错误.

I must now 'import' import java.nio.file.Path, otherwise I get a compiler error.

所以我的问题是:

  1. 如果filePath 确实是java.nio.file.Path 的一个实例,为什么不需要我需要导入它在第一个示例中,并且

  1. If filePath is indeed an instance of java.nio.file.Path, why don't I need to import it in the first example, and

如果使用 lambda 表达式在幕后"执行导入,那么为什么 do 我需要添加 importPath 的实例作为参数?

If using the lambda expression performs the import "under the covers," then why do I need to add the import when I create a method that takes an instance of Path as an argument?

可在 filePathpassedFilePath 上调用的方法是相同的,让我相信它们都是 java.nio.file.Path.

The methods available to call on both filePath and passedFilePath are identical, leading me to believe they are both instances of java.nio.file.Path.

推荐答案

import 声明并不是要声明您的代码正在使用哪些类;他们只是声明要使用什么来解析不合格的标识符.因此,如果您在代码中使用非限定标识符 Path,则必须使用 import java.nio.file.Path; 声明它应该解析为该限定类型.顺便说一下,这不是解析名称的唯一方法.名称也可以通过类继承来解析,例如如果它们与继承的成员类的简单名称匹配.

import declarations are not meant to declare what classes your code is using; they just declare what to use to resolve unqualified identifiers. So if you are using the unqualified identifier Path in your code you have to use import java.nio.file.Path; to declare that it should get resolved to this qualified type. This is not the only way to resolve a name, by the way. Names can also get resolved through the class inheritance, e.g. if they match the simple name of an inherited member class.

如果您隐式使用类型而不引用其名称,则不需要 import 语句,这不仅限于 lambda 表达式,它甚至不是 Java 8 的特殊功能.例如.与

If you are using a type implicitly without referring to its name you don’t need an import statement, that’s not limited to lambda expressions, it is not even a special Java 8 feature. E.g. with

Files.walk(Paths.get("C:/Users/mbmas_000/Downloads/SEC Edgar"), 1)

您已经隐式使用了 Path 类型,因为它是 Paths.get 的返回类型和 Files.walk 的参数类型,换句话说,您正在接收 java.nio.file.Path 的实例并将其传递给另一个方法而不引用其类型名称,因此您不需要 import.此外,您正在调用接受任意数量的 FileVisitOption 实例的可变参数方法.您没有指定任何内容,因此您的代码将创建一个零长度的 FileVisitOption[] 数组并将其传递给 Files.walk,同样,没有 import.

you are already using the Path type implicitly as it’s the return type of Paths.get and a parameter type of Files.walk, in other words, you are receiving an instance of java.nio.file.Path and passing it to another method without referring to its type name, hence you don’t need an import. Further you are calling a varargs method accepting an arbitrary number of FileVisitOption instances. You are not specifying any, therefore your code will create a zero-length FileVisitOption[] array and pass it to Files.walk, again, without an import.

通过改进的类型推断,还有另一种使用类型而不引用其名称的可能性,例如如果你打电话:

With the improved type inference, there is another possibility to use a type without referring to its name, e.g. if you call:

Files.newByteChannel(path, new HashSet<>());

您不仅为 varargs 参数创建了一个零长度的 FileAttribute[] 数组,而没有按名称引用此类型,您还创建了一个 HashSet不按名称引用类型 OpenOption.所以这也不需要,导入 java.nio.file.attribute.FileAttributejava.nio.file.OpenOption.

You are not only creating a zero length FileAttribute[] array for the varargs parameter without referring to this type by name, you are also creating a HashSet<OpenOption> without referring to the type OpenOption by name. So this also doesn’t require neither, importing java.nio.file.attribute.FileAttribute nor java.nio.file.OpenOption.

所以最重要的是,您是否需要 import 不取决于类型的使用,而是您是否通过它的简单名称来引用它(并且有不止一种使用方式一种没有按名称引用它的类型).在您的第二个示例中,您指的是方法 printPath(PathpassedFilePath) 中的名称 Path;如果您将其更改为 printPath(Object passedFilePath),则无需显式 importjava.nio.file.Path,一切都会再次运行.

So the bottom line is, whether you need an import does not depend on the use of the type but whether you refer to it by its simple name (and there are more than one way to use a type without referring to it by name). In your second example you are referring to the name Path in your method printPath(Path passedFilePath); if you change it to printPath(Object passedFilePath), everything will work again without an explicit import of java.nio.file.Path.

这篇关于Java Lambda 表达式是否利用“隐藏"?或本地包进口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆