[JAVA] 패키지

SungBum Park·2021년 3월 7일
0

JAVA

목록 보기
7/9
post-thumbnail

package 키워드

패키지(Package)는 클래스나 인터페이스 등을 모은 단위로서, 관련 클래스를 그룹화하고 포함된 클래스의 네임스페이스를 정의하는 역할을 수행한다. 여기서 네임스페이스는 이름을 구분할 수 있게 해주는 공간을 의미하며, 식별자 역할을 한다고 볼 수 있다. 자바는 네임스페이스 역할을 패키지로서 제공하고 있다.

패키지는 기본적으로 다음과 같이 표현한다.

상위패키지.하위패키지.클래스이름
  • 상위패키지.하위패키지 는 물리적인 형태로 파일 시스템으로 나타낸다. (Ex. me.codemcdme/codemcd/)
  • 클래스이름 은 위 패키지 형태의 파일 시스템 내부의 .class 파일이다.

위와 같이 상위패키지.하위패키지.클래스이름 으로 패키지 이름 + 클래스 이름을 함께 표현한 것을 FQCN(Fully Qualified Class Name) 이라고 한다. 자바에서 같은 이름의 클래스를 사용할 수 있는 이유는 사실 FQCN이 다르기 때문이다. 물론 FQCN이 완전히 같은 이름은 중복해서 사용할 수 없다.

예를 들어, 자주 사용하는 String 클래스는 java.lang 패키지 이름을 가지고 있으며, FQCN은 java.lang.String 이다.

public static void main(String[] args) {
        String s = "Hello";
        java.lang.String fqcnS = " world!";
        System.out.println(s + fqcnS);
}

위 코드와 같이, String 으로 단순히 쓸 수 있는 이유는 import 문을 사용하기 때문이다. 항상 FQCN으로 클래스를 정의하려면 매우 번거로운 작업이므로, import 문으로 이를 생략하여 사용한다. 하지만 String 클래스는 import 문을 선언하지 않아도 사용할 수 있다. 그 이유는 java.lang 은 자바에서 기본적으로 빌트-인 패키지이고, 자동으로 포함해주는 패키지이다.

빌트-인 패키지(Built-In Package)

자바는 기본적으로 여러 클래스를 내부적으로 제공해주는 언어이다. 이러한 클래스들은 물론 패키지 형태로 제공되며, 이러한 패키지들을 빌트-인 패키지 또는 predefined packages 라고 부른다. 이 패키지들은 JDK/JRE 내부에 포함되어 있어, 이를 다운로드받을 때 같이 온다.

빌트-인 패키지 종류

여기서, java.lang 패키지는 자바에서 기본적으로 포함되어 있어, import 문을 선언할 필요가 없다. 하지만 다른 빌트-인 패키지는 improt 문을 선언해서 사용해야 한다.(물론, 선언하지 않고 FQCN 으로도 사용 가능함.)

Built in packages in Java - Predefined packages - RefreshJava

패키지 선언

패키지를 선언하는 방법은 다음과 같다.

package me.codemcd;

public class Hello {
	public static void miain(String[] args) {
		System.out.println("Hello World!");
	}
}

위 코드와 같이 자바 코드 파일(.java) 맨 위의 위치에 package 상위패키지.하위패키지; 의 형태로 선언할 수 있다. 클래스 이름은 해당 자바 코드 파일의 클래스 이름이 등록된다. 만약 하나의 자바 코드 파일 내부에 여러 클래스를 선언하면, 다 같은 패키지로 등록이 된다.

위 코드를 콘솔에서 실행해보자.

  • 자바 코드 파일 컴파일
# javac -d <클래스 파일을 생성할 디렉토리 경로> <자바 코드 파일>
javac -d . Hello.java

컴파일 결과로, 패키지로 선언된 디렉토리 경로를 자동으로 생성하여 그 내부에 Hello.class 파일이 생성된다.

  • 자바 실행
java me.codemcd.Hello
Hello World!

import 키워드

import 키워드는 위에서 살펴봤듯이, 다른 패키지에 있는 클래스 또는 인터페이스를 참조하기 위함이다. 이를 참조하여, 내부의 클래스 또는 인터페이스를 FQCN을 사용할 필요없이 간단하게 사용할 수 있다.

import 문은 다음과 같이 선언한다.

import FQCN;

import 를 하기 위해서는 기본적으로 FQCN을 정확히 선언해주어야 한다. 하지만 만약 같은 패키지의 여러 클래스를 하나의 import 문으로 사용하고 싶다면, 클래스 이름 대신 * 를 사용할 수 있다.

import me.codemcd.Hello;
import me.codemcd.*;

하위 패키지가 다르다면, 반드시 import 문을 새로 선언해주어야 한다.

정적(static) 메서드를 컴파일 시점에 import도 가능하다.

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

클래스패스

클래스패스(CLASSPATH)는 이름 그대로, 클래스 또는 패키지를 찾을 때 기준이 되는 경로로서 JVM과 Java 컴파일러가 사용하는 파라미터이다.

대표적으로 컴파일 된 자바 파일(.class)를 실행할 때 JVM, 정확히는 클래스로더(System Classloader)는 지정된 클래스패스를 기준으로 클래스를 찾는다.

Hello.java 예제에서 컴파일 후 다음과 같은 명령어로 실행했다.

java me.codemcd.Hello

CLASSPATH 환경변수

CLASSPATH 환경변수는 클래스패스를 환경변수로 설정하는 것이다. 환경변수는 운영체제에서 범위를 설정하는 것이므로, 현재 사용하고 있는 운영체제 시스템에서 공통적으로 사용할 수 있다.

클래스패스를 환경변수로 설정하는 것은 터미널에서 다음과 같은 명령어로 설정할 수 있다.

export CLASSPATH=<경로>

만약 위 Hello.java 를 실행하기 전에, 전혀 다른 경로의 클래스패스를 설정하면 어떻게 될까?

Hello.java가 컴파일해서 생기는 .class 파일 경로가 /home/java-project/hello 라고 가정하자.

export CLASSPATH=/home/java-project/another-hello

위를 설정한 후, 다시 자바를 실행하면 다음과 같은 에러 메시지가 발생한다.

오류: 기본 클래스 me.codemcd.Hello을() 찾거나 로드할 수 없습니다.

Hello.class 파일을 찾을 수가 없다는 뜻이다.

이를 간단히 해결할 수 있는 방법은 java 명령어로 실행할 때 classpath 옵션을 설정하는 것이다. 이 옵션은 환경변수보다 우선순위가 높으므로, 환경변수로 설정된 클래스패스를 무시하고 옵션으로 설정한 클래스패스로 동작한다. (IntelliJ IDEA와 같은 IDE 역시 실행할 때 기본적으로 classpath 옵션을 설정한다. 환경변수에 영향을 받지 않기 위함이다.)

classpath 옵션

java 명령어를 실행할 때 classpath 옵션을 설정하는 방법은 다음과 같다.

java -classpath <클래스 경로> <클래스 파일 이름>
java -cp <클래스 경로> <클래스 파일 이름>

위를 통해 다시 정상적인 클래스패스를 설정한 후 Hello.java 파일을 실행해보자.

java -classpath /home/java-project/hello me.codemde.Hello
java -cp /home/java-project/hello me.codemde.Hello
Hello World!

그 결과, 위와 같이 다시 정상적으로 실행되는 모습을 볼 수 있다.

접근지시자(Access Modifiers)

접근 지시자 또는 접근 제어자는 클래스와 클래스 내부의 멤버변수 및 메서드의 접근 범위를 정의하는 것이다.

접근 제어자 종류

참고자료


profile
https://parker1609.github.io/ 블로그 이전

0개의 댓글