我想知道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>
答案 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