Here is an example:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
Everything compiles and runs fine. However, when I move map.keySet() to another variable:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
I get an error thrown at me:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Set cannot be resolved to a type
at Test.main(Test.java:12)
Run Code Online (Sandbox Code Playgroud)
我理解为什么第二个例子出现错误,但为什么我第一个没有错误呢?如果map.keySet()不导入java.util.Set ,java编译器如何知道返回什么?
我也在其他编程语言中看到过这种行为,特别是C++.
我理解为什么第二个例子出现错误,但为什么我第一个没有错误呢?如果
map.keySet()没有导入,java编译器如何知道返回的内容java.util.Set?
它知道这两种方式 - 它是字节码中元数据的一部分.
它不知道的是你的意思Set<String>.导入只会更改源代码中名称的含义 - 并且该名称不会出现在第一段代码的源代码中.
导入声明允许通过由单个标识符组成的简单名称(第6.2节)引用命名类型或静态成员.
您没有在第一个示例中引用简单名称,因此上述优点无关紧要.
换句话说,导入只允许这一行(在第二个样本中有效):
java.util.Set<String> keys = map.keySet();
Run Code Online (Sandbox Code Playgroud)
写成:
Set<String> keys = map.keySet();
Run Code Online (Sandbox Code Playgroud)
就是这样.