首页 > 解决方案 > 为什么调用方法不需要导入类?

问题描述

前几天我偶然发现了一些奇怪的东西。

考虑以下代码(它收集给定 s 的不同字长计数String,但这并不重要):

static void collectByLambda(Collection<String> list) {
    Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
            Collectors.groupingBy(String::length),
            m -> m.keySet()
    ));
}

及其等效方法参考版本:

static void collectByMethodReference(Collection<String> list) {
    Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
            Collectors.groupingBy(String::length),
            Map::keySet
    ));
}

第一个(lambda)版本不需要您import java.util.Map编译,第二个版本需要。

为什么会这样?我可以想象这是因为第二个版本需要Map在编译时访问该类来构建引用;Map#keySet()但是如果它不导入,它怎么知道它甚至存在Map

标签: javacollectionsjava-8referencejava-stream

解决方案


请注意,这import只是一种允许您在代码中使用非限定类名的方法,仅此而已。

由于第一个示例从未明确提及类名Map,因此无需使用缩写符号,而第二个示例确实提到了它。请注意,当使用完全限定名称时,第二个示例将在没有导入的情况下工作:

static void collectByMethodReference(Collection<String> list) {
    Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
            Collectors.groupingBy(String::length),
            java.util.Map::keySet
    ));
}

推荐阅读