Java导入通配符未导入包内所有内容

3

我正在编写一个Java程序,其中包含一个有Action Listener的按钮:

    JButton button = new JButton("Change");
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText(textField.getText());
        }
    });

在文件的顶部,我有以下两个导入语句:

import java.awt.*;
import javax.swing.*;

我知道这是可怕的做法,我正在为考试而复习,写在页面顶部会更容易和更快。

然而,我遇到了一个错误,告诉我要导入 java.awt.event.ActionListener

如果 event 包在 java.awt 内,并且我使用通配符 * 导入了所有内容,那么为什么它没有被导入呢??


1
因为它不是递归的;在任何有用的意义上,x.y.z都不是x.y的子包。 - Oliver Charlesworth
包的明显层次结构 - jaco0646
2个回答

2

java.awt.* 不包含 java.awt.event.ActionListenerjava.awt.event 不是 java.awt 的子包。 import java.awt.event.* 将会包含 java.awt.event.ActionListener


我不太明白为什么java.awt.event不在java.awt中?难道java.awt.*不会包括java.awt.eventjava.*会包括java.awt吗? - user2397282
仅仅是为了避免使用通配符导入世界上所有的东西,因为如果允许这样做,编译应用程序可能需要很长时间。 - Krzysztof Cichocki

2
这里是Java语言规范中type-import-on-demand的定义:
引入一个类型时,可以使用type-import-on-demand声明来使得命名包或类型中所有可访问的类型在需要时被引入。
TypeImportOnDemandDeclaration:import PackageOrTypeName.*;
重要的是要理解这个术语:“一个命名包的所有可访问类型”指的是所有其package声明为*之前的那个特定类型。因此,如果一个类的包定义如下:
package my.pkg.name;

然后它将可用于import my.pkg.name.*,但如果一个类像这样被定义:

package my.pkg.name.subname;

如果这样做,它将无法通过 import my.pkg.name.* 进行使用,因为它不属于该包。 它具体属于 my.pkg.name.subname ,就Java而言,这是一个不同的包。

确实,Java实现通常期望将包按目录层次结构排序,因此 my.pkg.name.subname 的目录将位于 my.pkg.name 的目录下。 如果你考虑一下,假设你写了这个:

ls my/pkg/name/*

在该目录下,它的行为非常相似:它只会给出直接在该目录下的文件,而不是进一步在其下层目录中的目录。类型导入的需求语义基本相同(除了subname "directory"本身,因为它不是一个类型)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接