例如
import org.apache.nutch.plugin.Extension,
虽然多次使用,
我不太了解基本上做了什么。
编辑:org.apache.nutch.plugin
基本上是4个目录还是少于4个目录,就像名为org.apache
的目录一样?
答案 0 :(得分:38)
我认为您可能要问的问题是,“Java中的包是什么,以及import
关键字与它们的关系如何?”。您对目录结构的困惑可能源于这样一个事实,即其他一些语言具有include
指令,这些指令在编译时使用文件名在源代码中直接包含指定文件的内容。 C / C ++是使用此类include
指令的语言示例。 Java的import
关键字不能以这种方式工作。正如其他人所说,import
关键字只是引用包中一个或多个类的简便方法。实际工作由Java虚拟机的类加载器完成(详情如下)。
让我们从“{x}}中描述的”Java包“的定义开始:
Java包是一种机制 将Java类组织成 名称空间类似于模块 MODULA。 Java包可以存储在 压缩文件称为JAR文件, 允许类下载速度更快 一个群体,而不是一次一个群体。 程序员通常也会使用 用于组织类所属的包 属于同一类别或提供 类似的功能。
在Java中,类的源代码文件实际上是由目录组织的,但Java虚拟机(JVM)定位类的方法与C / C ++等语言不同。 / p>
假设您的源代码中有一个名为“com.foo.bar”的包,并且在该包中有一个名为“MyClass”的类。在编译时,该类的源代码在文件系统中的位置必须是{source}/com/foo/bar/MyClass.java
,其中{source}
是您正在编译的源树的根。
Java和C / C ++等语言之间的一个区别是类加载器的概念。实际上,类加载器的概念是Java虚拟机架构的关键部分。类加载器的工作是找到并加载程序所需的任何class
文件。 “原始”或“默认”Java类加载器通常由JVM提供。它是Wikipedia article类型的常规类,包含一个名为ClassLoader
的方法,其定义如下:
// Loads the class with the specified name.
// Example: loadClass("org.apache.nutch.plugin.Extension")
Class loadClass(String name)
这个loadClass()
方法将尝试找到具有给定名称的类的class
文件,并生成一个loadClass()
对象,该对象具有能够实例化的Class
方法上课。
类加载器在哪里搜索class
文件?在JVM的类路径中。类路径只是可以找到class
个文件的位置列表。这些位置可以是包含class
个文件的目录。它甚至可以包含jar
个文件,这些文件本身可以包含更多class
个文件。默认的类加载器能够查看这些jar
文件以搜索class
个文件。作为旁注,您可以实现自己的类加载器,例如,允许搜索网络位置(或任何其他位置)的class
文件。
所以,现在我们知道“com.foo.bar.MyClass”是否在您自己的源代码树中的class
文件或class
内的jar
文件中在类路径的某个地方,类加载器会为你找到它,如果存在的话。如果它不存在,您将获得newInstance()
。
现在要解决import
关键字:,我将参考以下示例:
import com.foo.bar.MyClass;
...
public void someFunction() {
MyClass obj1 = new MyClass();
org.blah.MyClass obj2 = new org.blah.MyClass("some string argument");
}
第一行只是一种告诉编译器的方法“每当你看到一个简单地声明为MyClass
类型的变量时,假设我的意思是com.foo.bar.MyClass
。这就是{{1}的情况。在obj1
的情况下,你明确地告诉编译器“我不想要类obj2
,我实际上想要com.foo.bar.MyClass
”。所以org.blah.MyClass
关键字只是减少程序员为了使用其他类而必须执行的输入量的简单方法。所有有趣的东西都是在JVM的类加载器中完成的。
有关类加载器的确切内容的更多信息,我建议您阅读一篇名为ClassNotFoundException
答案 1 :(得分:13)
它正在做的就是节省你打字。每次要使用它时,都不必输入“org.apache.nutch.plugin.Extension”,导入允许您通过其简称“扩展名”来引用它。
不要被“import”这个词弄糊涂 - 它没有加载.class文件或类似的东西。类加载器将在CLASSPATH上搜索它,并在代码第一次需要时将其加载到perm空间。
更新:作为开发人员,您必须知道包与目录相关联。如果在.java文件中创建一个包“com.foo.bar.baz”,它必须存储在com / foo / bar / baz目录中。
但是当您下载一个JAR文件时,就像Apache Nutch库一样,从您的角度来看,没有涉及目录。创建JAR的人必须压缩正确的目录结构,如果使用WinZip打开JAR,则可以将其视为.class文件的路径。在编译和运行时,您只需将JAR放在应用程序的CLASSPATH中。
答案 2 :(得分:2)
Imports只是提示编译器告诉他如何找出类的全名。
所以如果你有“import java.util。*;”并且在您的代码中,您正在执行类似“new ArrayList()”的操作,当编译器处理此表达式时,它首先需要找到ArrayList类型的完全限定名称。它通过导入列表并将ArrayList附加到每个导入来实现。具体来说,当它将ArrayList附加到java.util时,它将获得FQN java.util.ArrayList。然后它在其类路径中查找此FQN。如果找到具有这样名称的类,则它知道java.util.ArrayList是正确的名称。
答案 3 :(得分:1)
是“org.apache.nutch.plugin”本质上是4个目录吗?
如果您有一个名为org.apache.nutch.plugin.Extension
的类,那么它将作为文件org/apache/nutch/plugin/Extension.class
存储在类路径中的某个位置。因此根目录包含四个嵌套子目录(“org”,“apache”,“nutch”,“plugin”),这些子目录又包含类文件。
答案 4 :(得分:1)
import org.apache.nutch.plugin.Extension
是一个编译时快捷方式,允许您在不使用类的完全限定名称的情况下引用Extension类。它在运行时没有意义,它只是一种节省输入的编译时间技巧。
按照惯例,此类的.class文件将位于文件系统或jar文件中的org / apache / nutch / plugin文件夹中,其中任何一个都需要在类路径中,在编译时和运行。如果.class文件位于jar文件中,则该jar文件需要位于类路径中。如果.class文件位于文件夹中,则文件夹“org”的父文件夹需要位于类路径中。例如,如果该类位于文件夹c:\ myproject \ bin \ org \ apache \ nutch \ plugin中,则文件夹c:\ myproject \ bin将需要成为类路径的一部分。
如果您有兴趣在运行程序时找出加载类的位置,请使用-verbose:class
java命令行选项。它应该告诉你JVM找到了哪个文件夹或jar文件。
答案 5 :(得分:0)
基本上,当你创建一个类时,你可以声明它是一个包的一部分。我个人在做包装方面没有多少经验。但是,afaik,这基本上意味着你从org.apache.nutch.plugin包中导入Extension类。
答案 6 :(得分:0)
建立Thomas'答案,org.apache.nutch.plugin是您要导入的类文件的路径。我不确定这个特定的包,但通常你会有一个.jar文件,你添加到你的类路径,你的import语句指向目录“./[classpath]/[jarfile]/org/apache/的nutch /插件“
答案 7 :(得分:0)
您不能将名为org.apache
的目录作为包。编译器将无法理解该名称,并在从该包导入任何类时查找目录结构org/apache
。
另外,不要将Java import
语句与C #include
预处理器指令混淆。就像他们所说的那样,import
语句是一种速记,可以在引用类名时输入更少的字符。