【发布时间】:2014-08-05 18:16:13
【问题描述】:
importJava 中的语句:导入的类是链接还是复制?复制到同一个目录?编译时如何处理/加入这些类?
【问题讨论】:
-
我认为this question 接受的答案至少部分回答了您的问题,当它谈到编译字节码中的类表示以及类加载器的工作方式时。
importJava 中的语句:导入的类是链接还是复制?复制到同一个目录?编译时如何处理/加入这些类?
【问题讨论】:
它们既没有链接也没有复制。
可以编写完全没有 import 语句的 Java 代码。您需要完全限定 java.lang 之外的所有内容,而不是默认包中的所有内容:
java.util.ArrayList<Integer> intList = new java.util.ArrayList<Integer>();
导入类是一种方便,它允许程序员不必完全限定大多数类引用。它允许通过它们的简单名称来引用这些类。使用import 语句,不会进行复制,也不会进行链接。编译器已经在类路径中搜索正确的类,无论是导入的还是完全限定的。
【讨论】:
从技术上讲,两者都不是。 import 语句为常用的类提供了一个别名(它确实将名称拉入当前命名空间,但程序员必须解决歧义)。完全限定路径为运行时环境提供位置信息以加载类。
现在,一些 IDE 会将一些库复制到 dist 或 build 目录以简化执行环境(或为安装程序构建做准备)。这不应与链接或复制相混淆。
【讨论】:
编译器不会将来自其他类的二进制文件包含到您的类中。如果您在代码中使用 com.foo.bar.YourClass 等类的全名
com.foo.bar.YourClass instance = new com.foo.bar.YourClass();
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
然后在运行时 JVM 将尝试在类路径中指定的目录/jar 之一中找到 com/foo/bar/YourClass.class 二进制文件,然后将其加载并使用它。
现在在 Java 中你可以使用类名的缩写形式
YourClass
但是为了使它成为可能,您需要指定此类的二进制文件应位于的位置(它来自哪个包),以便可以在运行时加载它们。这个问题解决了import语句 where
import com.foo.bar.YourClass;
意味着无论我们在哪里使用YourClass,我们都在使用来自com.foo.bar 包的类。
这个规则的一个例外是当你使用编译常量时
class Base{
public static final SIZE = 100;
}
class Demo{
public static void main (String[] args){
System.out.println(Base.SIZE);
}
}
在编译 Demo 类后,在 Base 类中更改 SIZE 的值后仍会打印 100,除非您再次重新编译 Demo 类。
【讨论】: