导入是如何在 Java 中完成的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1053658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How is import done in Java?
提问by omg
For instance
例如
import org.apache.nutch.plugin.Extension,
though used many times,
虽然多次使用,
I've no much idea what is done essentially.
我不太清楚本质上做了什么。
EDIT: Is org.apache.nutch.plugin
essentially 4 directories or fewer than 4 like a directory named org.apache
?
编辑:org.apache.nutch.plugin
本质上是 4 个目录还是少于 4 个,就像一个名为 的目录org.apache
?
回答by duffymo
All it's doing is saving you typing. Instead of having to type "org.apache.nutch.plugin.Extension" every time you want to use it, the import allows you to refer to it by its short name, "Extension".
它所做的只是节省您的打字时间。不必在每次要使用它时都键入“org.apache.nutch.plugin.Extension”,导入允许您通过它的短名称“Extension”来引用它。
Don't be confused by the word "import" - it's not loading the .class file or anything like that. The class loader will search for it on the CLASSPATH and load it into perm space the first time your code requires it.
不要被“导入”这个词弄糊涂了——它不会加载 .class 文件或类似的东西。类加载器将在 CLASSPATH 上搜索它,并在您的代码第一次需要它时将它加载到永久空间中。
UPDATE: As a developer you have to know that packages are associated with directories. If you create a package "com.foo.bar.baz" in your .java file, it'll have to be stored in a directory com/foo/bar/baz.
更新:作为开发人员,您必须知道包与目录相关联。如果您在 .java 文件中创建一个包“com.foo.bar.baz”,它必须存储在目录 com/foo/bar/baz 中。
But when you download a JAR file, like that Apache Nutch library, there are no directories involved from your point of view. The person who created the JAR had to zip up the proper directory structure, which you can see as the path to the .class file if you open the JAR using WinZip. You just have to put that JAR in the CLASSPATH for your app when you compile and run.
但是,当您下载 JAR 文件(例如 Apache Nutch 库)时,从您的角度来看,不涉及任何目录。创建 JAR 的人必须压缩正确的目录结构,如果您使用 WinZip 打开 JAR,您可以将其视为 .class 文件的路径。您只需在编译和运行时将该 JAR 放在应用程序的 CLASSPATH 中。
回答by Itay Maman
Imports are just hints to the compiler telling him how to figure out the full name of classes.
导入只是提示编译器告诉他如何找出类的全名。
So if you have "import java.util.*;" and in your code you are doing something like "new ArrayList()", when the compiler processes this expression it first needs to find the fully qualified name of the type ArrayList. It does so by going thru the list of imports and appending ArrayList to each import. Specifically, when it appends ArrayList to java.util it get the FQN java.util.ArrayList. It then looks up this FQN in its class-path. If it finds a class with such a name then it knows that java.util.ArrayList is the correct name.
所以如果你有“import java.util.*;” 并且在您的代码中,您正在执行类似“new ArrayList()”的操作,当编译器处理此表达式时,它首先需要找到类型 ArrayList 的完全限定名称。它通过遍历导入列表并将 ArrayList 附加到每个导入来实现。具体来说,当它将 ArrayList 附加到 java.util 时,它会获得 FQN java.util.ArrayList。然后在它的类路径中查找这个 FQN。如果它找到一个具有这样名称的类,那么它就知道 java.util.ArrayList 是正确的名称。
回答by Thomas
Basically when you make a class you can declare it to be part of a package. I personally don't have much experience with doing packages. However, afaik, that basically means that you are importing the Extension class from the org.apache.nutch.plugin package.
基本上,当您创建一个类时,您可以将其声明为包的一部分。我个人没有太多做包的经验。但是,afaik,这基本上意味着您正在从 org.apache.nutch.plugin 包中导入 Extension 类。
回答by Norm MacLennan
Buliding off of Thomas'answer, org.apache.nutch.plugin is a path to the class file(s) you want to import. I'm not sure about this particular package, but generally you'll have a .jar file that you add to your classpath, and your import statement points to the directory "./[classpath]/[jarfile]/org/apache/nutch/plugin"
根据Thomas 的回答,org.apache.nutch.plugin 是您要导入的类文件的路径。我不确定这个特定的包,但通常你会有一个 .jar 文件添加到你的类路径中,你的导入语句指向目录“./[classpath]/[jarfile]/org/apache/纽扣/插件”
回答by Esko Luontola
is "org.apache.nutch.plugin" essentially 4 directories?
“org.apache.nutch.plugin”本质上是 4 个目录吗?
If you have a class whose name is org.apache.nutch.plugin.Extension
, then it is stored somewhere in the classpath as a file org/apache/nutch/plugin/Extension.class
. So the root directory contains four nested subdirectories ("org", "apache", "nutch", "plugin") which in turn contain the class file.
如果您有一个名称为 的类org.apache.nutch.plugin.Extension
,那么它将作为文件存储在类路径中的某处org/apache/nutch/plugin/Extension.class
。所以根目录包含四个嵌套的子目录(“org”、“apache”、“nutch”、“plugin”),这些子目录又包含类文件。
回答by Francois Gravel
import org.apache.nutch.plugin.Extension
is a compilation time shortcut that allows you to refer to the Extension class without using the class' fully qualified name. It has no meaning at runtime, it's only a compilation time trick to save typing.
import org.apache.nutch.plugin.Extension
是一个编译时快捷方式,允许您在不使用类的完全限定名称的情况下引用扩展类。它在运行时没有意义,它只是一个编译时节省输入的技巧。
By convention the .class file for this class will be located in folder org/apache/nutch/plugin either in the file system or in a jar file, either of which need to be in your classpath, both at compile time and runtime. If the .class file is in a jar file then that jar file needs to be in your classpath. If the .class file is in a folder, then the folder that is the parent of folder "org" needs to be in your classpath. For example, if the class was located in folder c:\myproject\bin\org\apache\nutch\plugin then folder c:\myproject\bin would need to be part of the classpath.
按照惯例,此类的 .class 文件将位于文件系统或 jar 文件中的文件夹 org/apache/nutch/plugin 中,无论是在编译时还是运行时,它们都需要在您的类路径中。如果 .class 文件位于 jar 文件中,则该 jar 文件需要位于您的类路径中。如果 .class 文件在文件夹中,则作为文件夹“org”的父文件夹的文件夹需要在您的类路径中。例如,如果类位于文件夹 c:\myproject\bin\org\apache\nutch\plugin 中,则文件夹 c:\myproject\bin 需要是类路径的一部分。
If you're interested in finding out where the class was loaded from when you run your program, use the -verbose:class
java command line option. It should tell you which folder or jar file the JVM found the class.
如果您有兴趣找出运行程序时从何处加载类,请使用-verbose:class
java 命令行选项。它应该告诉您 JVM 找到了该类的文件夹或 jar 文件。
回答by cd1
you can't have a directory named org.apache
as a package. the compiler won't understand that name and will look for the directory structure org/apache
when you import any class from that package.
您不能将目录命名org.apache
为包。编译器不会理解该名称,并且会org/apache
在您从该包中导入任何类时查找目录结构。
also, do not mistake the Java import
statement with the C #include
preprocessor instruction. the import
statement is, like they've said, a shorthand for you to type fewer characters when referring to a class name.
另外,不要将 Javaimport
语句与 C#include
预处理器指令混淆。import
正如他们所说,该语句是您在引用类名时键入更少字符的简写。
回答by William Brendel
I think the question you might be trying to ask is, "What are packages in Java, and how does the import
keyword relate to them?". Your confusion about directory structures might stem from the fact that some other languages have include
directives that use file names to literally include the contents of the specified file in your source code at compile time. C/C++ are examples of languages that use this type of include
directive. Java's import
keyword does not work this way. As others have said, the import
keyword is simply a shorthand way to reference one or more classes in a package. The real work is done by the Java Virtual Machine's class loader (details below).
我想您可能要问的问题是,“Java 中的包import
是什么,关键字与它们有什么关系?” . 您对目录结构的困惑可能源于这样一个事实,即某些其他语言具有include
使用文件名在编译时在源代码中逐字包含指定文件内容的指令。C/C++ 是使用此类include
指令的语言示例。Java 的import
关键字不是这样工作的。正如其他人所说,import
关键字只是一种引用包中一个或多个类的简写方式。真正的工作是由 Java 虚拟机的类加载器完成的(详情如下)。
Let's start with the definition of a "Java package", as described in the Wikipedia article:
让我们从“Java 包”的定义开始,如维基百科文章中所述:
A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Java packages can be stored in compressed files called JAR files, allowing classes to download faster as a group rather than one at a time. Programmers also typically use packages to organize classes belonging to the same category or providing similar functionality.
Java 包是一种将 Java 类组织到类似于 Modula 模块的命名空间中的机制。Java 包可以存储在称为 JAR 文件的压缩文件中,允许类作为一组而不是一次一个下载得更快。程序员通常还使用包来组织属于同一类别或提供类似功能的类。
In Java, source code files for classes arein fact organized by directories, but the method by which the Java Virtual Machine (JVM) locates the classes is different from languages like C/C++.
在Java中,类的源代码文件是实际上是由目录组织,而是由Java虚拟机(JVM)所在的班级方法是像C / C ++语言的不同。
Suppose in your source code you have a package named "com.foo.bar", and within that package you have a class named "MyClass". At compile time, the location of that class's source code in the file system must be {source}/com/foo/bar/MyClass.java
, where {source}
is the root of the source tree you are compiling.
假设在您的源代码中有一个名为“com.foo.bar”的包,并且在该包中您有一个名为“MyClass”的类。在编译时,该类的源代码在文件系统中的位置必须是{source}/com/foo/bar/MyClass.java
,{source}
您正在编译的源代码树的根在哪里。
One difference between Java and languages like C/C++ is the concept of a class loader.In fact, the concept of a class loader is a key part of the Java Virtual Machine's architecture. The job of the class loader is to locate and load any class
files your program needs. The "primordial" or "default" Java class loader is usually provided by the JVM. It is a regular class of type ClassLoader
, and contains a method called loadClass()
with the following definition:
Java 和 C/C++ 等语言之间的一个区别是类加载器的概念。事实上,类加载器的概念是 Java 虚拟机架构的关键部分。类加载器的工作是定位和加载class
您的程序需要的任何文件。“原始”或“默认”Java 类加载器通常由 JVM 提供。它是一个常规的 type 类ClassLoader
,并包含一个loadClass()
使用以下定义调用的方法:
// Loads the class with the specified name.
// Example: loadClass("org.apache.nutch.plugin.Extension")
Class loadClass(String name)
This loadClass()
method will attempt to locate the class
file for the class with given name, and it produces a Class
object which has a newInstance()
method capable of instantiating the class.
此loadClass()
方法将尝试为class
具有给定名称的类定位文件,并生成一个Class
对象,该对象具有newInstance()
能够实例化该类的方法。
Where does the class loader search for the class
file?In the JVM's class path. The class path is simply a list of locations where class
files can be found. These locations can be directories containing class
files. It can even contain jar
files, which can themselves contain even more class
files. The default class loader is capable of looking inside these jar
files to search for class
files. As a side note, you could implement your own class loader to, for example, allow network locations (or any other location) to be searched for class
files.
类加载器在哪里搜索class
文件?在 JVM 的类路径中。类路径只是class
可以找到文件的位置列表。这些位置可以是包含class
文件的目录。它甚至可以包含jar
文件,而文件本身可以包含更多class
文件。默认的类加载器能够查看这些jar
文件以搜索class
文件。作为旁注,您可以实现自己的类加载器,例如,允许搜索网络位置(或任何其他位置)以查找class
文件。
So, now we know that whether or not "com.foo.bar.MyClass" is in a class
file in your own source tree or a class
file inside a jar
file somewhere in your class path, the class loader will find it for you, if it exists. If it does not exist, you will get a ClassNotFoundException
.
所以,现在我们知道无论“com.foo.bar.MyClass”是在class
你自己的源代码树中的一个文件中还是在你的类路径中某个class
文件中的一个jar
文件中,类加载器都会为你找到它,如果它存在。如果它不存在,您将获得一个ClassNotFoundException
.
And now to address the import
keyword:I will reference the following example:
现在来解决这个import
关键字:我将参考以下示例:
import com.foo.bar.MyClass;
...
public void someFunction() {
MyClass obj1 = new MyClass();
org.blah.MyClass obj2 = new org.blah.MyClass("some string argument");
}
The first line is simply a way to tell the compiler "Whenever you see a variable declared simply as type MyClass
, assume I mean com.foo.bar.MyClass
. That is what's happening in the case of obj1
. In the case of obj2
, you are explicitly telling the compiler "I don't want the class com.foo.bar.MyClass
, I actually want org.blah.MyClass
". So the import
keyword is just a simple way of cutting down on the amount of typing programmers have to do in order to use other classes. All of the interesting stuff is done in the JVM's class loader.
第一行是一个简单的方法来告诉编译器“每当你看到一个变量声明简单类型MyClass
,假设我的意思是com.foo.bar.MyClass
,这是正在发生的事情的情况下obj1
,在的情况下obj2
,您明确告诉编译器:“我真t想要类com.foo.bar.MyClass
,我实际上想要org.blah.MyClass
“。所以import
关键字只是减少程序员为了使用其他类而必须做的打字量的一种简单方法。所有有趣的东西都是在JVM的类加载器中完成的。
For more information about exactly what the class loader does, I recommend reading an article called The Basics of Java Class Loaders
有关类加载器的确切功能的更多信息,我建议阅读一篇名为The Basics of Java Class Loaders 的文章