为什么我可以在链接方法时省略 import 语句,但如果我单独调用它们则不能?

Why can I leave out an import statement when chaining methods, but not if I call them individually?

例如,在这个简单的 Java 程序中:

  1. 如果我写:

frame.getContentPane().add(button);

我只需要 import javax.swing.*; 代码就能完美编译。

  1. 但是,如果我写:

Container cont = frame.getContentPane(); cont.add(button);

我必须 import javax.swing.*;import java.awt.*; 才不会出现 cannot find symbol 编译器错误。

这两种写法在技术上不是完全一样的吗?为什么需要更少或更多的导入语句?

当我以示例中的第一种方式调用它时,getContentPane() 是否仍然是 return 容器类型对象,即使我可能没有使用容器引用来引用它变量?

您正在定义 java.awt.Container

类型的变量

由于 Container class 在此 package:java.awt.*, 中,因此您的 IDE 抱怨要求您也导入这些文件。

来自 Java 语言规范:

An import declaration allows a named type or a static member to be referred to by a simple name (§6.2) that consists of a single identifier.

Without the use of an appropriate import declaration, the only way to refer to a type declared in another package, or a static member of another type, is to use a fully qualified name (§6.7).

所以您需要 import 的唯一原因是您可以使用 "shortened" 类名。以下应该在不使用 import java.awt.* 的情况下工作:

java.awt.Container cont = frame.getContentPane();
cont.add(button);

您的代码的 "chaining" 版本隐式使用限定的类名,因此不需要 import 语句。

原因是因为java的import与其他语言有些不同。

在 Java 中,在运行期间 类路径中的所有 类 都存在 到 JVM。

导入语句实际上是为了帮助编译器识别您指的是哪个 Class,以防有许多 类 同名。

So, why are they not required when method chaining?

因为编译器可以很容易地知道特定方法返回的是哪种类型,所以永远不会有歧义。

当我们写:

frame.getContentPane().add(button);  

getContentPane() returns 运行 时的匿名容器对象,调用 add(button) 方法。如果您碰巧检查了 JFrame class,它将看起来像这样:

import java.awt.Container;
public class JFrame extends SomeClassName {  
    public Container getContentPane() {
        Container cont;
        //Some great code which assigns container with its appropriate value.
        return cont;
    }
} 

当我们写的时候:

Container cont = frame.getContentPane();  
cont.add(button);  

我们正在创建一个已知对象,即我们自己命名它,编译器必须知道 class 容器属于哪个包。