63

我想知道该import声明是如何工作的。

我问这个是因为我的imports项目中有以下内容:

import static com.googlecode.javacv.jna.highgui.cvCreateCameraCapture;
import static com.googlecode.javacv.jna.highgui.cvGrabFrame;
import static com.googlecode.javacv.jna.highgui.cvReleaseCapture;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.colorfulwolf.webcamapplet.gui.ImagePanel;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.jna.cxcore.IplImage;

我的项目中没有这些包,那么,如何导入?

如果我用我的所有类创建一个 JAR 文件,我的服务器将在哪里托管这个 JAR 文件,必须免费上网才能获得这些package

Applet有这些进口的问题,我在问这个问题,以了解是否可以成为互联网规则。

<applet code="com.colorfulwolf.webcamapplet.WebcamApplet"
archive="http://san.redenetimoveis.com/teste.jar, http://san.redenetimoveis.com/core.jar, http://san.redenetimoveis.com/javacv.jar, http://san.redenetimoveis.com/javase.jar, http://san.redenetimoveis.com/jna.jar, http://san.redenetimoveis.com/customizer.jar, http://san.redenetimoveis.com/jmf.jar, http://san.redenetimoveis.com/mediaplayer.jar, http://san.redenetimoveis.com/multiplayer.jar, http://san.redenetimoveis.com/sound.jar"
    height="550" width="550">
</applet>
4

5 回答 5

95

在动态语言中,当解释器imports 时,它只是读取一个文件并对其进行评估。

在 C 语言中,如果库是静态编译的,则外部库在编译时由链接器定位以构建最终对象,而对于动态库,则在运行时调用较小版本的链接器,它重新映射地址,从而使库中的代码可用到可执行文件。

在 Java 中,import编译器只是简单地使用它来让你用它们的非限定名称来命名你的类,比如说String而不是java.lang.String. 您实际上不需要导入java.lang.*,因为编译器默认会这样做。然而,这种机制只是为了节省你的打字时间。Java 中的类型是完全限定的类名,因此 a在代码运行时String实际上是一个对象。java.lang.String包旨在防止名称冲突并允许两个类具有相同的简单名称,而不是依赖于像这样为类型添加前缀的C 约定。java_lang_String. 这称为命名空间

顺便说一句,在 Java 中有静态导入构造,如果您使用来自某个类的大量常量,它可以进一步节省输入。在声明的编译单元(.java 文件)中

import static java.lang.Math.*;

您可以在代码中使用常量PI,而不是通过 引用它Math.PI,使用方法cos()而不是Math.cos(). 所以例如你可以写

double r = cos(PI * theta);

一旦您了解类在最终字节码中始终由其完全限定名称引用,您就必须了解类代码的实际加载方式。这发生在第一次创建该类的对象时,或者第一次访问该类的静态成员时。此时,ClassLoader尝试定位类并实例化它。如果找不到类,NoClassDefFoundError则抛出 a(ClassNotFoundException如果以编程方式搜索类,则为 aa)。要定位类,通常会检查环境变量ClassLoader中列出的路径。$CLASSPATH

要解决您的问题,您似乎需要这样的applet元素

<applet
  codebase = "http://san.redenetimoveis.com"
  archive="test.jar, core.jar"
  code="com.colorfulwolf.webcamapplet.WebcamApplet"      
  width="550" height="550" >

顺便说一句,您不需要在标准 JRE 中导入档案。

于 2012-09-27T11:53:05.070 回答
35

Java 的import语句是纯语法糖。import仅在编译时进行评估,以向编译器指示在代码中何处查找名称

当您总是指定类的完整限定名时,您可能没有任何 import 语句。就像这一行根本不需要 import 语句:

javax.swing.JButton but = new  javax.swing.JButton();

import 语句将使您的代码更具可读性,如下所示:

import javax.swing.*;

JButton but = new JButton();
于 2012-09-27T12:08:10.770 回答
3

Java 中的导入根本不起作用,因为它仅在编译时进行评估。(将其视为快捷方式,因此您不必编写完全限定的类名)。在运行时根本没有导入,只有 FQCN。

在运行时,类加载器必须能够找到您引用的所有类。(类加载器基础设施有时是黑魔法,并且高度依赖于环境。)如果是小程序,您必须正确装配 HTML 标签,并在服务器上提供必要的 JAR 档案。

PS:运行时匹配是通过限定的类名完成的——在这个名称下找到的类不一定与你编译的类相同或兼容。

于 2012-09-27T11:43:19.827 回答
1

javac(或java在运行时)查找classes正在导入的classpath. 如果它们不存在classpathclassnotfound抛出异常。

classpath就像pathshell 中的变量一样,shell 使用它来查找命令或可执行文件。

整个目录或单个 jar 文件可以放在classpath. 此外,是的,aclasspath可能包含一个不是本地但在 Internet 上某处的路径。请阅读有关类路径的更多信息以解决您的疑问。

于 2012-09-27T11:40:20.093 回答
0

您要导入的类必须在类路径上。因此,Applet 的用户必须将库放在正确的位置,或者您只需将这些库包含在您的 jar 文件中即可提供这些库。例如像这样:将发布合并到一个 JAR 文件中的最简单方法

于 2012-09-27T11:40:44.553 回答