Java导入如何工作?

时间:2012-09-27 11:30:04

标签: java

我想知道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文件,必须是免费的Internet访问才能获得这些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>

5 个答案:

答案 0 :(得分:83)

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

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

在Java中,编译器只使用import来让您按其不合格的名称命名您的类,假设String而不是java.lang.String。您实际上不需要导入java.lang.*,因为默认情况下编译器会执行此操作。但是这个机制只是为了节省一些打字。 Java中的类型是完全限定的类名,因此在运行代码时String实际上是java.lang.String对象。包旨在防止名称冲突,并允许两个类具有相同的简单名称,而不是依赖于像这样的前缀类型的 C约定。 java_lang_String。这称为命名空间

BTW,在Java中有静态导入结构,如果你使用来自某个类的大量常量,它允许进一步保存输入。在声明

的编译单元(.java文件)中
import static java.lang.Math.*;

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

double r = cos(PI * theta);

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

要解决您的问题,it seems您需要applet这样的元素

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

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

答案 1 :(得分:28)

Java的 import 语句是纯粹的语法糖。 import 仅在编译时进行评估,以向编译器指示在代码中的哪个位置找到名称

当您始终指定类的完全限定名称时,您可能没有任何import语句。像这一行根本不需要任何import语句:

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

import语句将使您的代码更具可读性:

import javax.swing.*;

JButton but = new JButton();

答案 2 :(得分:3)

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

在运行时,必须由类加载器找到您引用的所有类。 (类加载器基础结构有时是黑魔法并且高度依赖于环境。)对于applet,您必须正确地装配HTML标记并在服务器上提供必要的JAR存档。

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

答案 3 :(得分:1)

javac(或运行时java)查找classes中导入的classpath。如果它们不在classpath中,则会抛出classnotfound个例外。

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

可以将整个目录或单个jar文件放在classpath中。此外,是的classpath可能包括一个非本地但在互联网上的路径。请阅读有关classpath的更多信息以解决您的疑虑。

答案 4 :(得分:0)

您要导入的类必须位于类路径中。因此,要么Applet的用户必须将库放在正确的位置,要么只是通过将它们包含在jar文件中来提供这些库。例如:Easiest way to merge a release into one JAR file