5

好的,所以如果我有一个使用的项目:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Color;
import java.awt.Polygon;

是否会使 Class 文件更小以使用:

import java.awt.*

我正在考虑反对它,因为我正在导入很多我不需要的东西。我正在考虑它,因为它使文件的字符少了很多。

4

10 回答 10

17

没有不同。这些只是编译时构造。

于 2009-02-25T09:17:58.223 回答
13

不,根本没有区别。

根据The Java Virtual Machine Specifications, Second Edition , Chapter 5: Loading, Linking and Initializing说如下:

Java 虚拟机动态加载(第 2.17.2 节)、链接(第 2.17.3 节)和初始化(第 2.17.4 节)类和接口。加载是查找具有特定名称的类或接口类型的二进制表示并从该二进制表示创建类或接口的过程。链接是获取类或接口并将其组合到 Java 虚拟机的运行时状态以便可以执行的过程。

在编译时,没有类的链接,因此,使用通配符进行importing 没有区别。其他类不一起包含在结果class文件中。

实际上,如果您查看class文件的字节码(通过javap或此类反汇编程序),您将找不到任何import语句,因此在源代码中包含或多或少的import语句数不会影响class文件的大小。

这是一个简单的实验:尝试编写一个程序,并import使用通配符使用 s 进行编译,另一个使用显式导入进行编译。生成的class文件应该是相同的大小。


在特定类上使用显式import语句可能不太可读(而且很麻烦,如果不使用会为您编写它的 Eclipse 之类的 IDE),但允许您处理两个包中类名的重叠。

例如,在和包List中都有一个类。通过导入这两个包,名为 的类将发生冲突:java.utiljava.awtList

import java.util.*;
import java.awt.*;

// ... snip ... //

List l;    // which "List" are we talking about?

通过仅导入您需要的特定类,可以在一定程度上避免这些冲突:

import java.util.Hashmap;
import java.awt.List;

// .. snip ... //
List l;    // Now we know for sure it's java.awt.List

当然,如果您必须同时使用两者java.util.Listjava.awt.List那么您就不走运了;您需要明确使用其完全限定的类名。

于 2009-02-25T09:25:35.490 回答
3

Javaimport语句不会给类文件增加任何大小。它允许编译器在编译时推断出名称所指的内容。

唯一的区别是线

import java.util.*;

使您可以编写:

Set<String> set;

而不是:

java.util.Set<String> set;
于 2009-02-25T09:20:52.163 回答
2

首先,一定要看看我的“Import on Demand is Evil!” 文章:

http://javadude.com/articles/importondemandisevil.html

永远不应该使用 * 语法!当代码添加到另一个库时,它可能会导致您的程序停止编译!

现在这里是 import 的真正工作原理:

当你说

import a.b.c.Foo;

所有这一切都是告诉编译器,当你说“Foo”时,你的意思是“abcFoo”。然后编译器将在生成的字节码中用 abcFoo 替换所有出现的 Foo。

当你说

import a.b.c.*;

这告诉编译器“当你看到一个你不认识的符号 XXX 时,检查是否有 abcXXX”如果找到,编译器会将生成的字节码中的 XXX 替换为 abcXXX。

如果多个“*”导入与未知符号匹配,您将因歧义而收到编译器错误。

于 2009-02-25T22:02:55.203 回答
1

我认为Java只包含你真正需要的东西......所以使用一种或另一种方式的最终编译版本不会有任何区别。

于 2009-02-25T09:16:27.667 回答
1

老实说,你为什么关心你的类文件的大小?

更好的做法是显式包含所有需要的类,而不是执行“import foo.bar.*”。

这使您的代码更具可读性和可维护性。

于 2009-02-25T09:16:59.083 回答
1

生成的类文件完全没有变化。

导入只对编译器有影响(如果它必须索引很多目录,这可能需要更长的时间),当然还有源代码(当你可以准确地看到使用了哪些类时,IMO 更易于维护) .

于 2009-02-25T09:18:40.860 回答
1

如果你有兴趣使班级规模更小,游戏制作比赛java4k有一些技巧,例如,这个页面http://www.ahristov.com/tutorial/java4k-tips/java4k-tips.html

于 2009-02-25T10:18:35.753 回答
0

与以前的帖子中所述没有区别,但是作为偏好,我使用严格导入,因为我发现它使代码更易于阅读

于 2009-02-25T09:34:06.063 回答
0

作为对先前答案的补充,您应该看到的唯一区别是编译应该更快一些,当您明确告诉您想要什么import而不是提供通配符时,它可以包括数千个(成千上万)不必要的包和类.

于 2009-02-25T09:49:22.923 回答