Guide to Java Packages – Java包指南

最后修改: 2018年 12月 19日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this quick tutorial, we’ll cover the basics of packages in Java. We’ll see how to create packages and access the types we place inside them.

在这个快速教程中,我们将介绍Java中包的基础知识。我们将看到如何创建包和访问我们放在包里的类型。

We’ll also discuss naming conventions and how that relates to the underlying directory structure.

我们还将讨论命名惯例以及这与底层目录结构的关系。

Finally, we’ll compile and run our packaged Java classes.

最后,我们将编译并运行我们打包好的Java类。

2. Overview of Java Packages

2.Java包的概述

In Java, we use packages to group related classes, interfaces, and sub-packages.

在Java中,我们使用包来分组相关的类、接口和子包

The main benefits of doing this are:

这样做的主要好处是。

  • Making related types easier to find – packages usually contain types that are logically related
  • Avoiding naming conflicts – a package will help us to uniquely identify a class; for example, we could have a com.baeldung.Application, as well as com.example.Application classes
  • Controlling access – we can control visibility and access to types by combining packages and access modifiers

Next, let’s see how we can create and use Java packages.

接下来,让我们看看如何创建和使用Java包。

3. Creating a Package

3.创建一个包

To create a package, we have to use the package statement by adding it as the very first line of code in a file.

要创建一个包,我们必须使用package语句,将其作为文件中的第一行代码加入

Let’s place a type in a package named com.baeldung.packages:

让我们把一个类型放在一个名为com.baeldung.packages的包中。

package com.baeldung.packages;

It’s highly recommended to place each new type in a package. If we define types and don’t place them in a package, they will go in the default or unnamed package. Using default packages comes with a few disadvantages:

强烈建议将每个新类型放在一个包中。如果我们定义了类型而没有将它们放在一个包中,它们将进入default或未命名的包。使用默认包会有一些缺点。

  • We lose the benefits of having a package structure and we can’t have sub-packages
  • We can’t import the types in the default package from other packages
  • The protected and package-private access scopes would be meaningless

As the Java language specification states, unnamed packages are provided by the Java SE Platform principally for convenience when developing small or temporary applications or when just beginning development.

正如Java语言规范所述,Java SE平台提供的未命名包主要是为了在开发小型或临时应用程序或刚开始开发时提供方便。

Therefore, we should avoid using unnamed or default packages in real-world applications.

因此,我们应该避免在现实世界的应用中使用未命名的或默认的包

3.1. Naming Conventions

3.1.命名规则

In order to avoid packages with the same name, we follow some naming conventions:

为了避免同名的包,我们遵循一些命名惯例。

  • we define our package names in all lower case
  • package names are period-delimited
  • names are also determined by the company or organization that creates them

To determine the package name based on an organization, we’ll typically start by reversing the company URL. After that, the naming convention is defined by the company and may include division names and project names.

为了确定基于组织的包的名称,我们通常会从颠倒公司的URL开始。之后,命名规则由公司定义,可能包括部门名称和项目名称。

For example, to make a package out of www.baeldung.com, let’s reverse it:

例如,要从www.baeldung.com中制作一个包,让我们把它倒过来。

com.baeldung

We can then further define sub-packages of this, like com.baeldung.packages or com.baeldung.packages.domain.

然后我们可以进一步定义其中的子包,如com.baeldung.packagescom.baeldung.packages.domain.

3.2. Directory Structure

3.2.目录结构

Packages in Java correspond with a directory structure.

Java中的包与一个目录结构相对应。

Each package and subpackage has its own directory. So, for the package com.baeldung.packages, we should have a directory structure of com -> baeldung -> packages.

每个包和子包都有自己的目录。因此,对于包com.baeldung.packages,我们应该有一个com -> baeldung -> packages的目录结构。

Most IDE’s will help with creating this directory structure based on our package names, so we don’t have to create these by hand.

大多数IDE会根据我们的软件包名称帮助创建这个目录结构,所以我们不必手工创建这些。

4. Using Package Members

4.使用软件包成员

Let’s start by defining a class TodoItem in a subpackage named domain:

让我们先在一个名为domain的子包中定义一个TodoItem类。

package com.baeldung.packages.domain;

public class TodoItem {
    private Long id;
    private String description;
    
    // standard getters and setters
}

4.1. Imports

4.1.进口

In order to use our TodoItem class from a class in another package, we need to import it. Once it’s imported, we can access it by name.

为了从另一个包的类中使用我们的TodoItem类,我们需要导入它。一旦它被导入,我们就可以通过名称来访问它。

We can import a single type from a package or use an asterisk to import all of the types in a package.

我们可以从一个包中导入一个单一的类型,或者使用星号来导入一个包中的所有类型。

Let’s import the entire domain subpackage:

让我们导入整个domain子包。

import com.baeldung.packages.domain.*;

Now, let’s import only the TodoItem class:

现在,让我们只导入TodoItem类。

import com.baeldung.packages.domain.TodoItem;

The JDK and other Java libraries also come with their own packages. We can import pre-existing classes that we want to use in our project in the same manner.

JDK和其他Java库也有自己的包。我们可以以同样的方式导入我们想在项目中使用的预先存在的类。

For example, let’s import the Java core List interface and ArrayList class:

例如,让我们导入Java核心List接口和ArrayList类。

import java.util.ArrayList;import java.util.List;

We can then use these types in our application by simply using their name:

然后我们可以在我们的应用程序中使用这些类型,只需使用其名称即可:

public class TodoList {
    private List<TodoItem> todoItems;

    public void addTodoItem(TodoItem todoItem) {
        if (todoItems == null) {
            todoItems = new ArrayList<TodoItem>();
        }
        todoItems.add(todoItem);
    }
}

Here, we’ve used our new classes along with Java core classes, to create a List of ToDoItems.

在这里,我们使用我们的新类和Java核心类,来创建一个ListToDoItems.

4.2. Fully Qualified Name

4.2.完全合格的名称

Sometimes, we may be using two classes with the same name from different packages. For example, we might be using both java.sql.Date and java.util.Date. When we run into naming conflicts, we need to use a fully qualified class name for at least one of the classes.

有时,我们可能会使用来自不同包的两个同名的类。例如,我们可能同时使用java.sql.Datejava.util.Date当我们遇到命名冲突时,我们需要至少为其中一个类使用一个完全合格的类名。

Let’s use TodoItem with a fully qualified name:

让我们使用带有完全限定名称的TodoItem

public class TodoList {
    private List<com.baeldung.packages.domain.TodoItem> todoItems;

    public void addTodoItem(com.baeldung.packages.domain.TodoItem todoItem) {
        if (todoItems == null) {
            todoItems = new ArrayList<com.baeldung.packages.domain.TodoItem>();
        }todoItems.add(todoItem);
    }

    // standard getters and setters
}

5. Compiling with javac

5.用javac进行编译

When it’s time to compile our packaged classes, we need to remember our directory structure. Starting in the source folder, we need to tell javac where to find our files.

当我们要编译打包的类时,我们需要记住我们的目录结构。从源文件夹开始,我们需要告诉javac哪里可以找到我们的文件。

We need to compile our TodoItem class first because our TodoList class depends on it.

我们需要先编译我们的TodoItem类,因为我们的TodoList类依赖于它。

Let’s start by opening a command line or terminal and navigating to our source directory.

让我们首先打开一个命令行或终端,并导航到我们的源代码目录。

Now, let’s compile our com.baeldung.packages.domain.TodoItem class:

现在,让我们编译我们的com.baeldung.packages.domain.TodoItem类。

> javac com/baeldung/packages/domain/TodoItem.java

If our class compiles cleanly, we’ll see no error messages and a file TodoItem.class should appear in our com/baeldung/packages/domain directory.

如果我们的类编译得很干净,我们就会看到没有错误信息,一个文件TodoItem.class应该出现在我们的com/baeldung/packages/domain目录中。

For types that reference types in other packages, we should use the -classpath flag to tell the javac command where to find the other compiled classes.

对于引用其他包中的类型,我们应该使用-classpath标志来告诉javac命令在哪里找到其他编译的类。

Now that our TodoItem class is compiled, we can compile our TodoList and TodoApp classes:

现在我们的TodoItem类已经编译完成,我们可以编译我们的TodoListTodoApp类。

>javac -classpath . com/baeldung/packages/*.java

Again, we should see no error messages and we should find two class files in our com/baeldung/packages directory.

同样,我们应该没有看到错误信息,我们应该在com/baeldung/packages目录下找到两个类文件。

Let’s run our application using the fully qualified name of our TodoApp class:

让我们使用TodoApp类的完全合格名称来运行我们的应用程序。

>java com.baeldung.packages.TodoApp

Our output should look like this:

我们的输出应该看起来像这样。

packages

6. Conclusion

6.结语

In this short article, we learned what a package is and why we should use them.

在这篇短文中,我们了解了什么是包,以及为什么我们应该使用它们。

We discussed naming conventions and how packages relate to the directory structure. We also saw how to create and use packages.

我们讨论了命名规则以及包与目录结构的关系。我们还看到了如何创建和使用包。

Finally, we went over how to compile and run an application with packages using the javac and java commands.

最后,我们讨论了如何使用javacjava命令来编译和运行一个带有软件包的应用程序。

The full example code is available over on GitHub.

完整的示例代码可在GitHub上获得