Java包和类名混淆

时间:2010-07-16 06:03:18

标签: java packages

假设某处导入javax.servlet.http.HttpServlet

我的问题:

  1. 这是否意味着:我可以找到一个像javax / servlet / http这样的文件夹结构,里面会出现HttpServlet.class文件?

  2. 如果没有,可以找到这个类文件的确切位置?

  3. 这是否意味着:这些只是嵌套的命名空间,与文件夹结构无关?

  4. 上述导入中的包名称为javax.servletjavax.servlet.http?可能两者都是包,第一个是后者的超级包?

  5. 这个类文件实际上是如何包含的?我读过import并不像c / c ++ include。

  6. 感谢。

6 个答案:

答案 0 :(得分:2)

  1. 它也可以在jar文件中(在javax / servlet / http目录中)
  2. 否(见1.)
  3. 更确切地说,它是父包
  4. Imports可以访问正在编译的文件外部的类。 .class文件包含对所需外部类的引用。常量(最终静态变量)可以内联(它们的值由编译器在使用它们的代码中插入)。

答案 1 :(得分:2)

  1. 见1.

  2. 见1.

  3. 包名称为javax.servlet.http

  4. 类加载器将在运行时找到类(来自其类路径)

答案 2 :(得分:2)

  

1 - 这是否意味着:我可以找到像javax/servlet/http这样的文件夹结构,在HttpServlet.class文件中会出现?

在这种情况下,本身可能不在文件系统中。 (此类是J2SE运行时库的一部分。)

  

2 - 如果没有,那么这个类文件到底在哪里?

在JVM的类路径或bootclasspath上的JAR文件中。 JAR文件是包含.class个文件和其他资源的存档。 JAR文件中的类的路径名为/javax/servlet/http/HttpServlet.class。 (在本例中为rt.jar文件中的类。)

  

3 - 这是否意味着:这些只是嵌套的命名空间,与文件夹结构无关?

没有。如果类路径上有文件系统文件夹,则可以搜索它们以在JAR文件之前或之后查找类,具体取决于它们在类路径上的位置。类路径有效地覆盖了名称空间。 JAR文件的命名空间可以覆盖文件系统文件夹的命名空间,反之亦然,具体取决于有效的类路径。

  

4 - 上面提到的导入中的包名是javax.servlet还是javax.servlet.http?

javax.servlet.http

  

4续 - 可能两个都是包,第一个是后者的超级包?

两者都是包,但Java中没有“超级包”这样的东西。就Java语言而言javax.servletjavax.servlet.http是不相关的包。有些人可能会说javax.servletjavax.servlet.http的父包,但是这种语句从Java语言的角度来看没有内在意义。明显的亲子关系纯粹是传统的。

  

5 - 这个类文件实际上是如何包含的?我读过import并不像C / C ++ include。

在任何意义上,类文件都不是“包含”的。 Java import只是一个简写,它允许您引用导入的名称而不用其完整的包名限定它。

答案 3 :(得分:1)

  

这是否意味着:我可以找到一个文件夹   结构如javax / servlet / http   在某处和里面   HttpServlet.class文件将是   本?

是(很可能打包在jar文件中)

Package name in the above mentioned import would be
     

javax.servlet或javax.servlet.http?   可能两者都是包装和第一个   一个是后者的超级包装?

是的再次

  

这个类文件实际上是怎样的   包括在内呢?我读过import并不像   c / c ++ include。

导入packagename.classname并且必须在类声明ex:

之前
import javax.servlet.http.HttpServlet;

答案 4 :(得分:1)

完全限定的类名一个包名(命名空间)和类名组成。我们举一个简单的例子:

 java.lang.Object

(简单)类名为Object,包名为java.lang。在JLS中有一个实用的建议,即构造一个包含由点分隔的标识符的包名。这很实用,因为这样我们可以将包名称映射到文件夹结构。上面示例中的packagename映射到./java/lang,完全限定的类名为二进制文件./java/lang/Object.class,源文件为./java/lang/Object.java

这使得类加载器很容易在文件系统上找到类文件。类加载器简单地计算文件夹的名称空间(packagename)和类文件名的简单类名。

一个常见的误解是思考,包名称有些层次化。这不是真的。包com.example.beancom.example.bean.impl之间没有关系。第一个不是一种父包。

答案 5 :(得分:0)

对于更高级别的答案:包名称是一种创建命名空间的方式 - 没有命名空间的层次结构。但是,实际的类(使用完全限定名称,例如javax.servlet.http.HttpServlet)需要由ClassLoader加载。

JVM使用的沼泽标准ClassLoader是java.net.URLClassLoader的实例(嗯,是子类)。这可以在给定目录或JAR文件的起点的情况下查找类。包名称覆盖在文件系统结构上以获取类的位置。

还有其他ClassLoader - 大多数也在某种程度上遵循这个约定,但它只是一个约定。 ClassLoaders可以加载他们选择的类,包括动态生成它们。

对于javax.servlet.http.HttpServlet,您可能会在名为servlet.jarj2ee.jar的jar中找到类文件。有一个名为JFind的简洁实用程序可以帮助您找到可以找到类的位置 - 在IDE中通常也很容易。

对于问题5 - 正如其他人所提到的,import语句只是将导入的类或包带入本地名称空间,允许您使用方便的短名称HttpServlet而不是使用长名称{{ 1}}每次你需要引用它。你可以用Java编程,如果你愿意,也不要使用import语句,尽管人们很可能会奇怪地看着你。