자바 패키지
1. 개요
자바 패키지는 자바 소스 파일 내 클래스들을 묶는 단위로, `package` 키워드를 사용하여 선언하며, 소스 파일당 하나의 패키지만 선언할 수 있다. 다른 패키지의 클래스를 사용하기 위해 `import` 문을 사용하며, 클래스의 정규화된 이름을 직접 사용할 수도 있다. 패키지 선언이 없으면 익명 패키지에 속하게 되며, 패키지 전체를 설명하는 문서는 `package-info.java` 파일에 Javadoc 형식으로 작성한다. 패키지 접근 제어는 `public`, `private`, `protected` 및 default(package-private) 접근 권한을 통해 이루어진다. JAR 파일은 `jar` 명령어를 사용하여 생성하며, 패키지 명명 규칙은 충돌을 방지하기 위해 계층 구조를 따른다. 자바 SE 버전별 주요 패키지 목록과 Java SE 9 이후 모듈 시스템에 대한 정보도 포함한다.
이미지 준비중입니다.
| 유형 | 프로그래밍 언어 |
|---|---|
| 설계자 | 제임스 고슬링 |
| 개발자 | 오라클 |
| 최초 출시일 | 1995년 5월 23일 |
| 안정화 버전 | 21.0.2 (2024년 1월 16일) |
| 최신 미리보기 버전 | 22-ea+13 (2024년 1월 18일) |
| 운영 체제 | 크로스 플랫폼 |
| 라이선스 | GNU 일반 공중 사용 허가서 버전 2 (일부 구성 요소) 자바 라이선스 |
| 웹사이트 | java.com |
| 파일 확장자 | .java .class .jar .war .ear |
|---|---|
| 영향을 받은 언어 | C 언어 C++ 에이다 스몰토크 Objective-C 파스칼 |
| 영향을 준 언어 | C# 코틀린 스칼라 그루비 J# 자바스크립트 PHP 파이썬 루비 ActionScript D Ceylon Xtend Processing Vala |
| 종류 | 클래스 기반 언어, 객체 지향 프로그래밍 |
| 구현 언어 | C 언어 |
2. 패키지 사용
자바 소스 파일에서 `import` 문을 사용하면 다른 패키지에 속한 클래스를 불러와 사용할 수 있다. `import` 문은 다음과 같이 사용한다.
```java
import java.awt.event.*;
```
위 코드는 `java.awt.event` 패키지의 모든 클래스를 가져온다. 특정 클래스만 가져오려면 다음과 같이 작성한다.
```java
import java.awt.event.ActionEvent;
```
위 코드는 `java.awt.event` 패키지에서 `ActionEvent` 클래스만 가져온다.
`import` 선언을 사용하면, 가져온 클래스를 간단한 이름으로 참조할 수 있다.
```java
ActionEvent myEvent = new ActionEvent();
```
`import` 선언 없이 클래스의 전체 이름을 사용하여 클래스를 참조할 수도 있다.
```java
java.awt.event.ActionEvent myEvent = new java.awt.event.ActionEvent();
2.1. 패키지 선언
자바 소스 파일에서 `package` 키워드는 이 파일의 클래스나 클래스들이 속하는 패키지를 지정한다. 이 키워드는 일반적으로 소스 파일에서 처음 오는 키워드이다. 하나의 소스 파일에는 하나의 패키지만 선언할 수 있다.
```java
package com.example.myapp;
2.2. 클래스 가져오기 (Import)
`import` 문을 사용하면 다른 패키지의 클래스를 현재 소스 파일에서 사용할 수 있다. 특정 클래스만 가져오려면 `import com.example.myapp.MyClass;`와 같이 쓰고, 패키지의 모든 클래스를 가져오려면 `import com.example.myapp.*;`와 같이 쓴다. `import` 없이 전체 클래스 이름을 사용하여 클래스를 참조할 수도 있다.
```java
import java.awt.event.*;
```
위 코드는 `java.awt.event` 패키지로부터 모든 클래스들을 가져온다.
```java
import java.awt.event.ActionEvent;
```
위 코드는 해당 패키지에서 `ActionEvent` 클래스만 가져온다.
```java
ActionEvent myEvent = new ActionEvent();
```
위와 같이 `import` 선언 뒤에 단순한 클래스 이름을 사용하여 `ActionEvent` 클래스를 참조할 수 있다.
```java
java.awt.event.ActionEvent myEvent = new java.awt.event.ActionEvent();
```
위와 같이 클래스들은 `import` 선언 없이 직접 사용할 수도 있다.
2.3. 익명 패키지 (Unnamed Package)
패키지를 선언하지 않으면 클래스는 익명 패키지에 속하게 된다. 익명 패키지의 클래스는 다른 패키지에서 가져올 수 없다. 공식 자바 튜토리얼에서는 이러한 방식을 권장하지 않는다.
일반적으로 익명 패키지는 소규모 또는 임시 애플리케이션을 만들거나 개발 프로세스를 시작할 때만 사용한다. 그렇지 않은 경우 클래스와 인터페이스는 이름을 가진 패키지에 속해야 한다.
2.4. 패키지 전체 Javadoc 및 애노테이션
Javadoc 형식으로 작성되는 전체 패키지 설명 문서는 `package-info.java` 파일에 작성된다. 이 파일은 패키지 내 모든 클래스에서 사용될 주석을 포함할 수 있다. 자바 SE 5부터 추가된 애노테이션은 패키지에도 적용 가능하다.
패키지에 애노테이션을 추가하려면 패키지 디렉터리에 `package-info.java` 파일을 생성하고 다음과 같이 작성한다.
```java
/**
* 패키지 설명.
* 패키지 주석에는 Javadoc 태그를 사용할 수 있다.
*/
@Deprecated package com.example.wikipedia;
```
위 예시는 `com.example.wikipedia` 패키지를 사용 중단으로 표시한다. `package-info.java`는 자바 컴파일러가 경고를 표시하게 할 뿐만 아니라, Javadoc에서 패키지 설명을 표시하는 문서를 생성하는 데에도 사용된다. `package-info.java`는 패키지에 애노테이션을 추가하기 위해 만들어졌으며, 기존의 `package.html`을 대체한다.
3. 패키지 접근 제어
자바 패키지는 클래스와 멤버의 접근 범위를 제어하는 데 사용된다. 패키지 내의 클래스는 'default'(package-private) 접근 권한으로 선언된 클래스와 멤버에 접근할 수 있으며, 클래스나 멤버가 `public`, `protected`, `private`로 선언되지 않은 경우 기본 접근 권한이 적용된다.
3.1. 접근 제한자
공개(public) 멤버와 클래스는 어디에서나 볼 수 있으며, 비공개(private) 멤버는 동일한 클래스 내에서만 볼 수 있다. 패키지 내의 클래스는 기본(default, package-private) 접근 권한으로 선언된 클래스와 멤버는 물론, `protected` 접근 제어자로 선언된 클래스 멤버에도 접근할 수 있다. 클래스 또는 멤버가 `public`, `protected`, `private`로 선언되지 않은 경우 기본(package-private) 접근 권한이 적용된다.
다른 패키지의 클래스는 기본 접근 권한으로 선언된 클래스와 멤버에 접근할 수 없다. 그러나 `protected`로 선언된 클래스 멤버는 선언 클래스의 하위 클래스(서브클래스)인 다른 패키지의 클래스뿐만 아니라 동일한 패키지의 클래스에서도 접근할 수 있다.
4. JAR 파일 생성
`jar` 명령 줄 유틸리티를 사용하여 클래스 파일들을 JAR 파일로 압축할 수 있다. 다음은 그 예시이다.
```java
jar cf myPackage.jar *.class
```
위 명령어는 확장자가 `.class`인 모든 파일을 `myPackage.jar`라는 JAR 파일로 압축한다. 명령 줄 옵션 'c'는 `jar` 명령어에 "새 아카이브 생성"을 지시하고, 'f' 옵션은 파일 생성을 지시한다. 파일 이름은 그 다음에 오며, JAR 파일의 내용물 앞에 지정된다.
5. 패키지 명명 규칙
패키지는 계층 구조 명명 패턴을 사용하여 정의되며, 계층 구조의 각 레벨은 마침표(`.`, "dot"으로 발음)로 구분된다. 자바 언어 사양은 널리 배포될 패키지가 고유한 네임스페이스를 갖도록 고유한 패키지 이름을 만드는 방법을 설명하는 명명 규칙을 설정한다.
일반적으로 패키지 이름은 조직의 도메인 이름을 역순으로 시작한다. 예를 들어, 한국에 있는 MySoft라는 조직이 분수를 처리하는 패키지를 만들 경우, `kr.co.mysoft.fractions`와 같이 명명하여 다른 회사에서 만든 유사한 패키지와 구별한다. 패키지 이름의 후속 구성 요소는 조직 자체의 내부 명명 규칙에 따라 달라진다.
패키지 이름은 모두 소문자로 작성하는 것이 관례이다. 하이픈(-)이 포함된 도메인 이름은 밑줄(_)로 대체하여 Java소스 코드에서 사용한다.
6. Java SE 버전별 주요 패키지
Java SE는 여러 버전이 있으며, 각 버전마다 주요 패키지가 조금씩 다르다.
| 패키지 이름 | 설명 |
|---|---|
| `java.lang` | import 문 없이 사용 가능한 기본 기능 및 유형 |
| `java.util` | 컬렉션 자료 구조 클래스 |
| `java.io` | 파일 작업 |
| `java.math` | 다중 정밀 산술 |
| `java.nio` | 논블로킹 I/O 프레임워크 |
| `java.net` | 네트워킹, 소켓, DNS 조회 |
| `java.security` | 키 생성, 암호화/복호화 |
| `java.sql` | 자바 데이터베이스 연결 (JDBC) |
| `java.awt` | 네이티브 GUI 컴포넌트 기본 계층 |
| `java.text` | 텍스트, 날짜, 숫자, 메시지 처리 (자연어 독립적) |
| `java.rmi` | RMI 패키지 |
| `java.time` | 날짜, 시간 관련 API |
| `java.beans` | JavaBeans 구성 요소 관련 |
| `java.applet` | 애플릿 생성 및 통신 |
6.1. Java SE 8 핵심 패키지
| java.lang | import 문을 사용하지 않고도 사용할 수 있는 기본 언어 기능 및 기본 유형. |
|---|---|
| java.util | 컬렉션 자료 구조 클래스 |
| java.io | 파일 작업 |
| java.math | 다중 정밀 산술 |
| java.nio | 자바용 논블로킹 I/O 프레임워크 |
| java.net | 네트워킹 작업, 소켓, DNS 조회 등 |
| java.security | 키 생성, 암호화 및 복호화 |
| java.sql | 데이터베이스에 접근하기 위한 자바 데이터베이스 연결 (JDBC) |
| java.awt | 네이티브 GUI 컴포넌트용 패키지의 기본 계층 구조 |
| java.text | 자연어에 독립적인 방식으로 텍스트, 날짜, 숫자 및 메시지를 처리하기 위한 클래스와 인터페이스를 제공합니다. |
| java.rmi | RMI 패키지를 제공합니다. |
| java.time | 날짜, 시간, 순간 및 기간에 대한 주요 API. |
| java.beans | JavaBeans 구성 요소와 관련된 클래스 및 인터페이스를 포함합니다. |
| java.applet | 애플릿을 생성하고 통신하기 위한 클래스 및 메서드를 제공합니다. |
6.2. Java SE 9 이후 모듈 시스템
자바 9(2017년 9월 21일 출시)에서 프로젝트 직소 개발 노력의 결과로, 일종의 패키지 모음인 "모듈" 지원이 구현되었다. 이 "모듈"은 이전에는 "슈퍼 패키지"라고 불렸으며 원래 자바 7용으로 계획되었다.
모듈은 소스 파일 계층 구조의 루트에 있는 module-info.java 파일에 배치된 선언에서 종속성을 설명한다. 자바 9 이후, JDK는 컴파일 시간과 런타임 모두에서 모듈 종속성을 확인할 수 있다. JDK 자체는 자바 9용으로 모듈화되었다.
7. 추가 정보(Java SE 5의 애노테이션)
Java SE 5부터 추가된 애노테이션은 패키지에도 적용할 수 있다. 패키지에 애노테이션을 적용하려면 해당 패키지 디렉터리에 `package-info.java` 파일을 만들고 패키지 관련 애노테이션을 작성한다.
```java
/**
* 패키지 설명.
* 패키지 코멘트에는 Javadoc의 태그를 그대로 사용할 수 있다.
*/
@Deprecated package com.example.wikipedia;
```
위 예시는 `com.example.wikipedia` 패키지를 사용 중단으로 표시하는 것이다. 이 `package-info.java` 파일은 Java 컴파일러가 경고를 표시하도록 하는 것 외에도 Javadoc에서 패키지 설명을 표시하는 문서를 생성하는 데에도 사용된다. `package-info.java`는 패키지에 애노테이션을 붙이기 위해 만들어졌으며, 기존의 `package.html`을 대체한다.