2009-07-06 23 views
34

我是一个新手,刚学到了,如果我定义说在Java文件中定义一个包的目的是什么?

package my.first.group.here; 
... 

那么Java文件,这些文件在此方案将my/first/group/here目录下放置。

将某些Java文件放入包中的主要目的是什么?另外,如果我选择采用这种方式,我应该如何对它们进行分组?

谢谢


编辑:任何人谁可能再有同样的问题,我只是发现this tutorial on packages从Sun

回答

32

让我们从一个“Java包”的定义开始,如Wikipedia article描述:

Java包是 机制组织Java类到 命名空间类似于 MODULA的模块。 Java包可以存储在 被称为JAR文件的压缩文件中, 允许类以更快的速度下载,而不是一次一个。程序员通常还使用 程序包来将属于 的类组织到同一类别或提供类似的功能 。

所以此基础上,包在Java中只是用来组织类和防止类名称冲突的机制。你能说出他们任何你想要的,但Sun公司已经公布了一些naming conventions应该使用时包命名:

一个独特的包名的前缀 总是写在所有-lowercase ASCII 字母应该是 顶级域名之一,目前COM, EDU,GOV,MIL,净,组织,或识别 国家的specifi的 英语双字母代码之一编辑在ISO标准 3166,1981年

包 名的后续部分根据不同的 机构自身的内部命名 约定。这样的约定可能会在 中指定某个目录名称为 的组件是部门,部门, 项目,机器或登录名。

实例:

  • com.sun.eng

  • com.apple.quicktime.v2

  • edu.cmu.cs.bovik.cheese

0

Wikipedia页的题目

“Java包是组织Java类成类似MODULA的模块命名空间的机制Java包可以存储在压缩文件名为JAR文件,允许类。作为一个组而不是一个一个地下载更快,程序员通常使用包来组织同属于同一类别的类或提供类似的功能。“

4

它允许程序由多个不同的程序/组件/库组成,因此它们的类名不会发生冲突,并且组件更容易组织。请参阅http://java.sun.com/docs/books/tutorial/java/package/index.html

在Java中,习惯上将包命名为反向域名。例如,如果您公司的域名是“initech.com”,并且您正在制作一个名为“Gizmo”的程序,则程序包名称通常以“com.initech.gizmo”为前缀,其中包含程序不同组件的子包。

2

包提供类分离的灵活性非常重要。它们可用于:

  • 分离项目
  • 分离模块
  • 分离应用层(业务,网络,DAO)
  • 进一步更细粒度码分离

例如

com.mycompany.thisproject.thismodule.web

可以指示某个模块的Web层。

10

我是一个大型的应用程序,你一定会有两个文件命名完全相同(java.util.Date和java.sql.Date),特别是当你开始引入第三方jar时。所以基本上,你可以使用包来确保唯一性。

最重要的是,在我看来,包装将项目分解成有意义的细分市场。所以我的SQL包具有与sql相关的代码,并且我的记录器包处理日志记录。

+1

“......你可以使用软件包来确保唯一性......”完全正确。高效术语是“划分全局命名空间”。您引用了java.util.Date和java.sql.Date。 – duffymo 2009-07-06 19:45:23

0

另外,如果我选择采用这种方式,我应该如何对它们进行分组?

这很大程度上取决于您在项目中使用的设计模式。大多数情况下(特别是,如果你很新的话),你会希望按功能或其他逻辑相似性对它们进行分组。

+0

此外,我还要补充说,“选择采用”并不是真正的选择,“必须采用”更符合现实。一般而言,在“默认”包中留下课程是令人不悦的。 – cjstehno 2009-08-31 19:58:59

0

Java在其实现中非常确切。它并没有真正留下冒险的余地。

如果每个人都使用相同的软件包,他们将不得不寻找一些“全球范围”的方式来确保没有两个类名冲突。

这可以让每一个班级都写入自己的“地方”,如果你不想看,你就不必看。

您可能在系统的4个不同位置定义了不同的“Point”对象,但是您的课程只会使用您期望的(因为您导入该课程)。

他们确保每个人都有自己的空间的方式是使用你的反向域,所以我的是“tv.kress.bill”。我拥有该域名 - 实际上我与我的兄弟“tv.kress.doug”分享,尽管我们共享相同的域名,但我们不能碰撞。

如果贵公司的一百个部门都是用Java开发的,那么他们可以在不碰撞的情况下知道如何划分它。

不做这种划分的系统现在对我来说看起来很片断。我可能会用它们来拼凑一些个人的脚本,但如果没有严格的包装,我会觉得不舒服。

0

其他人已经提供了非常特定于Java的答案,这很好,但这里有一个比喻:为什么要将文件组织到硬盘上的目录中?为什么不只是在一个目录中有一个平面文件系统?

答案当然是包提供组织。与数据库接口的程序部分与向用户显示UI的程序部分不同,因此它们将位于不同的包中。

与目录类似,它也提供了解决名称冲突的方法。你可以在两个不同的目录中有一个temp.txt,就像你可以有两个类出现在不同的包中一样。这变得很重要(1)当你开始将代码与其他人在互联网上结合起来时,或者(2)甚至意识到Java的类加载如何工作。

0

关于软件包的另一个重要的事情是用于访问控制的protected成员。

受保护位于公众(每个人都可以访问)和私人(只有班级内部可以访问)之间。标记为受保护的东西可以从相同的包或从子类中访问。这意味着对于有限的访问,您不必将所有内容放在同一个类中。

3

除了其他答案中提到的命名空间外,还可以根据该成员声明的范围限制对方法和字段的访问。 成员与公共范围都可以随意访问,限制访问你通常将它们定义为私人(即隐藏在类外)。 您也可以使用受保护的范围来限制对类型及其子类的访问。 也有默认范围(没有限定词的构件具有默认的范围),它允许子类型和类型中的构件相同的包的访问。这可以成为共享字段和方法的有效方式,而不会使其过于广泛,并且可以帮助进行测试。

例如,下面的方法对同一包中的所有其他成员都是可见的。

public class Foo { 
    int doSomething() { 
     return 1; 
    } 
} 

要测试您可以定义在同一个包另一种类型的(但可能是一个不同的源位置)的方法,该类型将能够访问该方法。

public class FooTest { 
    @Test 
    int testDoSomething() { 
     Foo foo = new Foo(); 
     assertEquals(1, foo.doSomething()); 
    } 
} 
1

最终,我们想要在Java中使用软件包有3个核心原因。

1)易于维护

组织classespackages如下的通过封装原理关注点分离并允许在整个系统的设计更好的凝聚力。更进一步,按功能打包允许开发团队找到相关的类和界面进行更改,支持敏捷方法中使用的缩放方法的垂直分片技术。欲了解更多信息,请参阅博文:Package your classes by Feature and not by LayersCoding: Packaging by vertical slice

2)提供包装安全

软件包允许外部访问只是public访问修饰符在包含类的方法。使用protected或不使用修饰符只能在同一个包中的类访问。欲了解更多信息,请参见后: Which Java access modifier allows a member to be accessed only by the subclasses in other package?

3)避免类似命名

到.NET的命名空间类似,类名都包含其包含的包的范围之内。这意味着两个互斥的包可以包含具有相同名称的类。这是因为软件包本身具有不同的名称,因此完全限定名称是不同的。有关更多信息,请参阅教程[命名软件包:Java教程] [3]。

相关问题