繁体   English   中英

为什么我不必导入在Java中不用作变量类型的类?

[英]Why don't I have to import classes not used as variable types in Java?

这是一个例子:

import java.util.HashMap;

public class Test
{
    public static void main(String[] args)
    {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("leorum", 1);
        map.put("ipsum", 2);
        map.put("dolor", 3);

        System.out.println(map.keySet().toString());
    }
}

一切都编译好,运行良好。 但是,当我将map.keySet()移动到另一个变量时:

import java.util.HashMap;

public class Test
{
    public static void main(String[] args)
    {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("leorum", 1);
        map.put("ipsum", 2);
        map.put("dolor", 3);

        Set<String> keys = map.keySet();
        System.out.println(keys.toString());
    }
}

我收到一个错误:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
    Set cannot be resolved to a type
    at Test.main(Test.java:12)

我理解为什么第二个例子出现错误,但为什么我第一个没有错误呢? java编译器如何知道map.keySet()返回而不导入java.util.Set?

我也在其他编程语言中看到过这种行为,特别是C ++。

我理解为什么第二个例子出现错误,但为什么我第一个没有错误呢? java编译器如何知道map.keySet()返回而不导入java.util.Set

它知道这两种方式 - 它是字节码中元数据的一部分。

它不知道的是Set<String> 导入只会更改源代码中名称的含义 - 并且该名称不会出现在第一段代码的源代码中。

JLS第7.5节开始

导入声明允许通过由单个标识符组成的简单名称(第6.2节)引用命名类型或静态成员。

您没有在第一个示例中引用简单名称,因此上述优点无关紧要。

换句话说,导入只允许这一行(在第二个样本中有效):

java.util.Set<String> keys = map.keySet();

写成:

Set<String> keys = map.keySet();

就是这样。

import指令是一种纯粹的语法特性,它允许您引用类型而不用包名限定它。

由于您的第一个代码从不引用Set类型,因此无需导入即可正常工作。

import使用类无关; 它只影响你如何写出它的名字。

java编译器知道map.keySet()返回什么,因为它在HashMap的定义中。

public Set<K> keySet() { ... }

编译HashMap时,编译器知道什么是Set<>因为在HashMap的源代码中有一个import语句(或者更确切地说,在这种情况下,不需要import语句,因为Set与HashMap在同一个包中)。

然后编译器将此信息放在已编译的类文件中,作为方法“签名”的返回类型。

当您使用map.keySet() ,您不必指定方法的返回类型,因为编译器可以访问HashMap的类文件,因此它知道它需要的所有内容。

因为在第一个示例中,keySet()在HashMap对象中执行,而不是在您的main中执行,这就是您不需要声明它的原因。

在第一种情况下, map.keySet()的类型是已知的。 返回类型是方法合同的一部分。

在第二种情况下,非限定名称Set不足以识别变量keys的类型。 完全限定的类型名称不是从作业的右侧推断出来的。 您可以完全限定名称,也可以导入名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM