본문 바로가기
Baeldung번역&공부/Java-basic

패키지에 대하여(Guide to Java Packages)

by ms727 2025. 2. 4.

원본 글: https://www.baeldung.com/java-packages

Java에서의 package에 대해 알아봅니다. 어떻게 packages를 만드는지, 어떻게 접근하는지 확인해볼 것입니다.
그리고 명명규칙과 디렉터리 구조와 어떻게 연관지어야할지도 확인해봅니다.

1. Overview of Java packages

Java에서는 packages를 통하여 클래스, 인터페이스, 등을 그룹화합니다.
이렇게 해서 얻는 이점들은 다음과 같습니다.

  • 관련 유형(타입)들을 좀 더 편하게 찾을 수 있게 합니다. - packages에는 일반적으로 논리적으로 연관된 유형이 포함되어있습니다.
  • 클래스 이름충돌 방지 - package는 클래스를 고유하게 식별하는데 도움을 줍니다.
  • 접근제한 제어 - 접근제한자를 통하여 특정 packages에 속한 클래스, 인터페이스 등에 대한 접근 제한을 지정할 수 있습니다.

2. Creating a Package

package를 만들려면 코드 파일안에 package라는 구문을 맨 윗줄에 추가하면 됩니다.

package com.minseok.packages;

package를 명시하여사용하는것을 권장하고 있는데, 만약 package를 명시하지 않으면 unnamed package나 default package에 들어가게됩니다. 그러면 몇 가지 단점들을 가질 수 있습니다.

  • package 구조와 sub-package라는 계층화된 구조를 구성 못할 수 있습니다.
  • 다른 packages에서 default package에 있는 것들은 불러오지 못할 수 있습니다(Import).
  • protectedprivate접근제한자의 의미가 없어집니다.

default package같은건 임시로 애플리케이션을 개발하거나 소규로 프로그램을 작성할 때 사용됩니다.

그러므로 우리는 unnamed package나 default package를 사용하는건 지양해야합니다.

2.1 Naming Conventions

package 이름이 겹치는 것을 피하기 위하여 몇가지 명명 규칙이 있습니다.

  • 모두 소문자로 작성합니다.
  • '.'으로 구분합니다.
  • package이름은 조직이나 회사의 규칙에 따라 명명될 수 있습니다.

보통 회사 도메인 주소를 반대로 뒤집은 것을 기준으로 작성합니다. 그 이후 부서나 프로젝트 팀단위로 패키지명을 구성할 수 있습니다.

예를 들어서 www.minseok.com이라는 도메인이 있으면 이를 뒤집어서 작성하면됩니다.

com.minseok

이후 sub-packages는 com.minseok.domain 또는 com.minseok.packages 처럼 구성할 수 있습니다.

2.2 Directory Structure

Packages는 디렉터리 구조와 대응됩니다.

각 package는 디렉터리를 가지고 있습니다. com.minseok.domain은 com/minseok/domain과 같은 디렉터리를 가집니다.
대부분 IDE에서는 package에 대응하여 디렉터리를 만들어줍니다. 따라서 개발자가 따로 만들어줄 필요는 없습니다.

3. Using Package Members

TodoItem이라는 클래스를 domain이라는 sub-package에 정의해봅니다.

package com.minseok.packages.domain;

public class TodoItem {
    private Long id;
    private String description;

    // standard getters and setters
}

3.1 Imports

만약 위의 TodoItem클래스를 다른 package에서 사용하고 싶다면 import라는 구문과 함께 해당 패키지이름을 넣어서 불러오면 됩니다.
'*'으로 해당 package에 있는 모든 타입들을 가져올 수 있습니다.

import com.minseok.packages.domain.*;
//한개만 명시적으로 가져오고 싶다면
import com.minseok.packages.domain.TodoItem;
//보통 많이 사용하는 ArrayList, List 불러오기
import java.util.ArrayList;import java.util.List;

Java의 여러 라이브러리들은 자신만의 package를 가지고 있습니다. 위와 동일한 방식으로 우리가 만드려는 프로젝트에 여러 클래스들을 불러올 수 있습니다. 이렇게 불러온 값들은 실제 코드에서 사용될 수 있습니다.

public class TodoList {
    private List<TodoItem> todoItems;

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

3.2 Fully Qualified Name

때때로 package명은 다르지만 클래스명은 같은 2개의 클래스가 있을 수 있습니다.
예를 들어서 java.sql.Data와 java.util.Date같은 것들입니다.
이렇게 충돌이 날 경우 명시적으로 package 경로를 지정하여 사용해야합니다.
다음과 같이 명시적으로 지정할 수 있습니다.

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

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

    // standard getters and setters
}

4. Compiling with javac

package화된 클래스를 컴파일할 때는 해당 디렉터리를 알고 있어야합니다. 왜냐하면 javac에게 해당 파일의 위치를 알려줘야하기 때문입니다.

위에서 TodoList는 TodoItem에 의존하고 있으므로 TodoItem이 먼저 컴파일해야합니다.

command line을 통하여 이를 먼저 컴파일 합니다.

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

컴파일이 깔끔하게 완료되면, 어떤 에러메시지도 보이지 않고 Todoitem.class라는 파일이 해당 디렉터리에 생기게 됩니다.
다른 package의 유형을 참조하는 경우, -classpath라는 플래그값을 통해 javac에게 해당 유형의 클래스파일들을 알려줘야합니다.

TodoItem 클래스는 컴파일 되었기에 TodoList와 TodoApp 클래스를 컴파일할 수 있습니다.

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

이 또한 컴파일이 제대로 수행되면 어떤 에러 메시지도 발생되지 않을 것이고, 2개의 .class파일을 com/minseok/packages 디렉터리에서 확인할 수 있습니다.

그 후 >java com.minseok.packages.TodoApp 명령어를 통해 애플리케이션을 수행할 수 있습니다.

5. 결론

package에 대해 왜 사용되는지, 무엇인지에 대해 학습하였습니다.

명명 규칙과 디렉터리 구조와 어떤 관계가 있는지도 확인하였고 이를 작성하는 법도 확인하였습니다.
그리고 이를 컴파일을하고 직접 실행하는 방법도 학습하였습니다.