我知道我可以使用import
语句在我的Java项目中包含一个类或一组类。
例如,import java.io.utils.*
包中的java.io.utils
导入(即可在我的Java程序中使用)所有类。
我的问题是,是否需要编译导入包中的类?或者包也可以包含未编译的Java文件?如果它可以是,我们何时可以使用类文件以及何时可以使用Java文件?
答案 0 :(得分:8)
导入只是意味着"通过简单的名称使导入的类可用" - 如果在任何地方使用完全限定名称,则可以完全删除导入。例如,它绝对不像C中的#include
。
当你编译时,如果你试图引用未编译的代码,它将在那时被编译,假设编译器可以猜测在哪里找到源代码。结果从不引用未编译的代码,因为编译器需要知道每个类型公开的内容。
作为完整示例,构造以下文件结构:
// src/foo/A.java
package foo;
import bar.*;
public class A {
public static void main(String[] args) {
B.sayHello();
}
}
// src/bar/B.java
package bar;
public class B {
public static void sayHello() {
System.out.println("Hello");
}
}
然后在src
目录中运行:
javac foo/A.java
这将自动编译bar/B.java
- 但不会编译任何其他未被引用的代码(可能是传递性的)。
我强烈建议不要使用这个"按需编译"尽管如此 - 如果编译依赖于B类的A类,它将编译B 第一个时间,但之后如果更改B并重新编译A,编译器将不会重新编译B我会将你的代码组织到适当的项目中,并且总是一次重新编译一个完整的项目,将项目的输出目录添加到依赖于它的项目的类路径中,而不是允许编译一个项目,按需重新编译另一个项目。
(请注意,这并不是在谈论许多IDE支持的渐进式编译......这是一个相当不同的问题,假设它已经正确实现,这很好。)
答案 1 :(得分:3)
与C不同,Java中的var page = require('webpage').create();
page.open('http://google.com', function () {
console.log(page.content);
phantom.exit();
});
不会“复制”内容。 Java中的包只是一种避免歧义的方法。 import
和javax.swing.Timer
不同java.utils.Timer
。当您说Timer
时,您告诉编译器您的意思是import javax.swing.Timer
,而不是任何其他javax.swing.Timer
。
您可以导入的所有这些内容都来自JDK或您正在使用的其他库,或者它们是由您创建的。属于前一类的类已经编译(.class)。当您执行Timer
时,您编译的类也会被编译。您不能引用任何未编译的类。由于它们是未编译的,因此计算机不知道它们存在。
在编译代码之前IDE了解您的包和类的原因是因为IDE很聪明。他们甚至在你注意到它之前编译你的代码。
答案 2 :(得分:0)
Java文档报告。
You might have to set your CLASSPATH so that the compiler and the JVM can find the .class files for your types.
link:https://docs.oracle.com/javase/tutorial/java/package/summary-package.html