| 백기선님의 라이브 스터디를 참고하여 작성한 게시물입니다.
비슷한 성격의 자바 클래스(+ interface, enum)들을 모아 놓은 자바의 디렉토리
클래스가 물리적으로 하나의 파일인 것과 유사하게, 패키지는 물리적으로 하나의 디렉토리이다.
예를 들어, java.lang.System 클래스는 java패키지의 하위 패키지인 lang에 속한다. 따라서 물리적으로 java디렉토리 밑의 lang디렉토리 밑의 System.class 파일이다.
클래스 파일의 최상단에는 소속 패키지를 선언하는 단일문이 위치해야 한다. (주석과 공백을 제외)
자바의 모든 클래스는 반드시 하나 이상의 패키지에 포함되어야 한다.
만약 클래스 파일에 package 선언문을 명시하지 않으면, 자바 컴파일러는 해당 클래스를 unnamed package
에 포함해 컴파일한다.
따라서 패키지를 명시하지 않은 모든 클래스와 인터페이스는 모두 같은 패키지에 포함되게 된다.
특정 패키지에 속한 클래스를 다른 파일에서 사용하기 위해서는, 클래스 이름 앞에 패키지의 경로까지 포함한 풀 네임을 명시해야 한다.
package myPackage;
public class MyClass {
public static void main(String[] args) {
otherPackage.OherClass otherInstance = new otherPackage.OherClass();
}
}
이를 import
키워드를 통해 개선할 수 있다
package myPackage;
import otherPackage.OherClass;
public class MyClass {
public static void main(String[] args) {
OherClass otherInstance = new OherClass();
}
}
import 문은 자바 컴파일러에 코드에서 사용할 클래스의 패키지에 대한 정보를 미리 제공하는 역할을 한다.
*
를 사용하는 것이, 해당 패키지에 포함된 다른 모든 하위 패키지의 클래스까지 포함해 주는 것은 아니다.import java.awt.*;
import java.util.*;
// 위와 아래는 다르다
import java.*;
java.lang
패키지는 명시적으로 import 하지 않아도 사용할 수 있다.package myPackage;
public class MyClass {
public static void main(String[] args) {
java.lang.Integer myInt = 1;
Integer yourInt = 2; // java.lang 생략 가능
}
}
아마 컴파일러가 자동으로 import java.lang
을 추가하는 것 같다.
JVM, 자바 컴파일러가 클래스나 패키지를 찾을 때 기준이 되는 경로를 의미한다.
class MyClass {
...
}
class Main {
public static void main(String[] args) {
MyClass myInstance = new MyClass();
}
}
위와 같은 두 개의 클래스가 존재하는 상황에서, 아래의 명령을 통해 컴파일 해보자
javac Main.java
그런 뒤 컴파일된 바이트코드를 실행해보자
java Main
정상적으로 실행되지 않는다. 무엇이 문제일까?
Exception in thread "main" java.lang.NoClassDefFoundError: MyClass
...(생략)...
JVM이 MyClass
클래스를 찾지 못했기 때문이다. JVM에게 MyClass
의 위치를 알려주자
classpath 옵션을 통해 JVM에게 클래스가 위치한 경로를 알려줄 수 있다
java -classpath ".;mypackage" Main
위 명령은 현재 위치(.)에서 클래스를 찾아서 실행하라, 없으면 mypackage에서 찾아라
는 의미다.
이 방법으로 클래스 경로를 알려줄 수 있으나, 클래스 개수가 늘어나거나, 클래스가 여기저기 흩어진 경우에는 사용이 불편하다.
환경변수는 운영체제에 지정하는 변수
자바 가상머신과 같은 애플리케이션들은 환경변수의 값을 참고해서 동작하게 된다.
자바는 환경변수 CLASSPATH
를 사용한다
환경변수 CLASSPATH
는 말 그대로 클래스패스 값을 저장한다.
이 값을 지정하면, 실행할 때마다 -classpath 옵션을 통해 경로를 일일이 지정하지 않아도 된다.
별도로 CLASSPATH를 설정하지 않으면 현재 경로
로 CLASSPATH가 설정된다.
문제가 생기면 추후에 알아보자;
접근지시자를 복습해보자
종류 | 접근 범위 | 동일 클래스 | 동일 패키지 | 다른 패키지의 자식 클래스 | 다른 패키지 |
---|---|---|---|---|---|
public | 제한 없음 | O | O | O | O |
protected | 동일한 패키지 && 상속받은 class 내부 | O | O | O | |
default | 동일한 패키지 | O | O | ||
private | 동일한 클래스 | O |