패키지란, 클래스의 묶음이다. 패키지에는 클래스 또는 인터페이스를 포함시킬 수 있으며, 서로 관련된 클래스들끼리 그룹 단위로 묶어 놓음으로써 클래스를 효율적으로 관리할 수 있다.
- 하나의 소스파일에는 첫 번째 문장으로 단 한번의 패키지 선언만을 허용한다.
- 모든 클래스는 반드시 하나의 패키지에 속해야 한다.
- 패키지는 점(.)을 구분자로 하여 계층구조를 구성할 수 있다.
- 패키지는 물리적으로 클래스 파일(.class)을 포함하는 하나의 디렉토리이다.
클래스가 물리적으로 하나의 클래스파일(.class)인 것과 같이 패키지는 물리적으로 하나의 디렉토리이다.
예를 들면, String클래스의 실제 이름은 java.lang.String이다. java.lang패키지에 속한 String클래스라는 의미이다. 이는 물리적으로 디렉토리 java의 서브디렉토리인 lang에 속한 String.class파일이라는 것을 뜻한다.
디렉토리가 하위 디렉토리를 가질 수 있는 것처럼, 패키지도 다른 패키지를 포함할 수 있다. lang패키지는 java패키지의 하위패키지이다.
package 패키지명;
패키지를 선언하려면 클래스나 인터페이스의 소스파일(.java)의 맨 위에 위와 같이 한 줄만 적으면 된다.
패키지명은 대소문자를 모두 허용하지만, 클래스명과 쉽게 구분하기 위해서 소문자로 하는 것을 원칙으로 하고 있다.
소스파일에 자신이 속할 패키지를 지정하지 않은 클래스는 자동적으로 '이름 없는 패키지'에 속하게 된다. 결국 패키지를 지정하지 않는 모든 클래스들은 같은 패키지에 속하는 셈이다.
package com.codechobo.book;
class PackageTest {
public static void main(String[] args) {
System.out.println("Hello World!")
}
}
위의 예제를 작성한 뒤 다음과 같이 '-d'옵션을 추가하여 컴파일한다.
C:\jdk1.8\work>javac -d . PackageTest.java
'-d'옵션 뒤에는 해당 패키지의 루트(root)디렉토리의 경로를 적어준다.
여기서는 현재 디렉토리(.) 즉, 'C:\jdk1.8\work'로 지정했기 때문에 컴파일을 수행하고 나면 book폴더에 PakageTest.class가 생성된다.
후에는 패키지의 루트 디렉토리를 클래스패스에 포함시켜야 실행 시 JVM이 PackageTest클래스를 찾을 수 있다. (제어판-시스템-고급 시스템 설정-환경 변수-새로 만들기)
클래스의 코드를 작성하기 전에 import문으로 사용하고자 하는 클래스의 패키지를 미리 명시해주면 소스코드에 사용되는 클래스이름에서 패키지명을 생략할 수 있다.
소스코드를 작성할 때 다른 패키지의 클래스를 사용하려면 패키지명이 포함된 클래스 이름을 사용해야 한다. 매번 패키지명을 붙여 사용해야하는 불편함을 import문으로 해결할 수 있다.
import문의 역할은 컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공하는 것이다.
컴파일 시에 컴파일러는 import문을 통해 소스파일에 사용된 클래스들의 패키지를 알아 낸 다음, 모든 클래스이름 앞에 패키지명을 붙여 준다.
▶ 이클립스는 단축키 'ctrl+shift+o'를 누르면 자동으로 import문을 추가해준다.
import 패키지명.클래스명;
or
import 패키지명.*;
import java.text.SimpleDateFormat;
import java.util.*;
키워드 import와 생략하고자 하는 클래스의 이름을 패키지명과 함께 써주면 된다.
'패키지명.*'을 이용해서 지정된 패키지에 속하는 모든 클래스를 패키지명 없이 사용할 수 있다.
클래스 이름을 지정해주는 대신 '*'을 사용하면, 컴파일러는 해당 패키지에서 일치하는 클래스이름을 찾아야 하는 수고를 더 해야 할 것이다. 단지 그 뿐이며 실행 시 성능상의 차이는 전혀 없다.
여기서 주의할 점은 import문에서 클래스 이름 대신 '*'를 사용하는 것이 하위 패키지의 클래스까지 포함하는 것은 아니라는 것이다. 'import java.*;로 적을 수 없다.
import문을 사용하면 클래스의 패키지명을 생략할 수 있는 것과 같이 static import문을 사용하면 static멤버를 호출할 때 클래스 이름을 생략할 수 있다.
import static java.lang.Integer.*; // Integer클래스의 모든 static메서드
import static java.lang.Math.random; // Math.random()만. 괄호 안붙임.
import static java.lang.System.out; // System.out을 out만으로 참조가능
만일 위와 같이 선언했다면, 다음과 할 수 있다.
System.out.println(Math.random());
▼
out.println(random());
참고서적
자바의 정석(저자: 남궁성)
import는 파이썬에서도 알던 개념이라 쉽게 이해할 수 있었다. 자바는 클래스를 많이 사용하고 패키지를 사용하므로 쓸 일이 많을 것 같다.
다음은 제어자의 개념에 대해 공부하겠다.