자바의 패키지에 대해 학습하세요
자바에서 패키지는 클래스의 묶음이며 클래스 또는 인터페이스를 포함시킬 수 있다. 관련된 클래스끼리 패키지 그룹 단위로 묶어 놓으며 클래스를 효율적으로 관리할 수 있게 한다.
지금까지 클래스를 클래스명만 가지고 구분했지만, 클래스의 실제 이름은 패키지명을 포함한 것이다.
String
-> java.lang.String
클래스가 물리적으로 하나의 클래스파일(.class)인 것과 같이 패키지는 물리적으로 하나의 디렉토리이다.
디렉토리가 하위 디렉토리를 가질 수 있는것처럼, 패키지도 다른 패키지를 포함할 수 있음 (.으로 구분)
java.lang.String
은 실제로 java/lang/String.class
에 위치하고 있다.
-
혹은 다른 특수문자(_
제외)를 허용하지 않음package 패키지명
).
을 구분자로 하여 계층구조로 구성할 수 있다.소스코드 작성시 다른 패키지의 클래스를 사용하기 위해 이용되는 키워드이다.
import를 이용해 사용하고자 하는 클래스의 패키지를 미리 명시하면, 소스코드에 사용되는 클래스 이름에서 패키지명은 생략할 수 있다.
java.util.List
를 사용하고자 한다면 다음과 같이 import를 이용할 수 있다.
import java.util.List;
또한 import문은 package와 달리 여러번 선언하여 사용할 수 있다.
.java 소스파일은 다음과 같이 구성한다.
만약 java.util 패키지의 여러 클래스를 사용한다면 다음과 같이 많은 import문을 선언해야한다.
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMAp;
이를 다음과 같이 한 문장으로 줄일 수 있다.
import java.util.*;
패키지명.*;
문법은 하위 클래스를 포함하지 않으므로 다음과 같이 사용할 수 없다.
import java.util.*;
import java.text.*;
// 아래와 같이 불가능
// import java.*;
자바는 java.lang.*;
의 클래스들을 묵시적으로 import해주기 때문에 String, System같은 클래스들을 import하지 않고 사용할 수 있고, 같은 패키지의 클래스또한 import없이 사용할 수 있다.
import를 사용하면 클래스의 패키지명을 생략하듯 static import를 이용하면 static 멤버를 호출할 때 클래스 이름을 생략할 수 있다. 특정 클래스의 static 멤버를 사용할 때 편리하다.
import static java.lang.Integer.*;
import static java.lang.Math.random;
...
// 다음과 같이 사용가능
int a = parseInt("1"); // Integer.parseInt();
System.out.println(random()); // Math.random() 생략
클래스패스는 JRE(Java Runtime Environment)가 클래스 및 기타 리소스 파일을 검색하는 경로입니다.
위는 Oracle docs에서 설명하는 클래스패스의 정의이다. 그렇다면 왜 하필 JDK가 아닌 JRE로 명시했을까?
클래스패스는 클래스의 경로 즉 .class
파일을 실행하기 위해 클래스의 위치를 참조하기 위한 경로이다.
.java 소스파일이 컴파일되면 컴파일된 자바의 바이트 코드(.class)들을 엮어서 JVM의 메모리영역인 Runtime Data Area
로 적재하는 역할을 한다. 이때 클래스패스가 이용된다.
따라서 JDK가 클래스패스를 이용한다고 말할 수 있지만, 좀 더 깊게 들어가면 JRE에서 이용한다고 볼 수 있다.
클래스패스를 지정하는 방식은 두 가지로 나뉜다.
CLASSPATH 환경변수
-classpath (-cp) 옵션
우선 환경변수를 설정하기 전에 클래스패스가 어디서부터 어디까지 지정해야할지 알아보자
앞에서 패키지를 설명할때 다른 패키지의 클래스를 이용하기 위해선 import문을 작성했다.
import java.util.List;
혹자는 import를 작성했으니 클래스패스는 파일 내부에 명시돼있는것 아니냐고 생각할 수 있지만, 클래스패스는 실제 내 컴퓨터의 클래스파일이 위치하는 패키지의 루트 디렉토리를 의미한다.
만약 c:/jdk1.8/mywork/com/myproject/Main.class
가 경로이고 내 프로젝트의 패키지는 com.myproject/Main.class
라면 c:/jdk1.8/mywork/
이 부분의 경로는 JRE가 알 수 없는것이다. 따라서, 클래스패스 환경변수에 해당 경로(패키지의 루트 디렉토리)를 포함시키면 JRE가 해당 클래스를 찾을 수 있다.
즉, 환경변수는 마치 전역변수처럼 클래스파일이 위치한곳을 어떤 위치에서 자바 애플리케이션을 실행할 수 있도록 해주며, 영구적인 특성을 가진다.
위의 프로그램은 다음과 같이 실행할 수 있다
java com.myproject.Main
만약 환경변수 설정을 하지 않았다면 다음과 같이 실행해야 한다.
java -cp c:\Java\test HelloWorld
운영체제에 따라 환경변수의 설정이 다르고 환경변수 설정 관련글은 매우 많으므로 직접 설명하진 않겠습니다.
-classpath 옵션은 클래스패스를 환경변수로 등록하여 사용하는것이 아닌 매 실행마다 클래스패스를 직접 입력하여 자바 응용 프로그램을 시작한다.
-cp라는 키워드로 이용할 수 도 있으며
예를 들어 Java JRE가 utility.myapp
패키지에서 Cool.class
를 찾아야 하고 해당 디렉터리의 경로가 C:\java\MyClasses\utility\myapp
이면 클래스 경로가 C:\java\MyClasses
를 포함하도록 설정합니다. 이 응용 프로그램을 실행하려면 다음 java 명령을 사용할 수 있습니다.
java -classpath C:\java\MyClasses utility.myapp.Cool
혹은
java -cp C:\java\MyClasses utility.myapp.Cool
와 같이 단축하여 사용할 수 있다.
-classpath는 javac, java 즉 컴파일과 프로그램 실행 둘 다에서 사용할 수 있는 옵션이다.
접근제어자는 클래스, 메소드, 필드에 붙일 수 있으며 해당 제어자가 붙게되면 위의 그림과 같이 접근할 수 있는 영역이 제한된다.