Live Study 7주차 - 패키지


package 키워드

패키지는 클래스의 묶음이며, 자바는 반드시 하나의 패키지에 속해야 한다.

패키지의 특징은 다음과 같다.

  • 점을 구분자로 하여 계층구조로 구성한다.
  • 패키지는 물리적으로 클래스 파일을 포함하는 하나의 디렉토리이다.

사실 클래스의 이름에도 패키지가 포함된다. 6주차 과제에서 공부한 Object 클래스의 getClass() 를 출력해보면, 클래스명과 패키지 경로가 포함되서 출력되는걸 볼 수 있다.

이름없는 패키지

위의 코드를 보면 패키지를 작성하지 않고 바로 클래스를 생성해서 컴파일링을 하였다. 자바에서는 반드시 하나의 패키지가 필요한데, 패키지가 작성하지 않았음에도 어떻게 컴파일링을 할 수 있었을까?

자바는 기본으로 이름없는 패키지(Unnamed package) 를 제공한다고 한다. 따라서 특별히 패키지를 작성하지 않으면, 자바에서 모든 인터페이스와 클래스를 이름없는 패키지로 하나의 패키지에 포함시키고 컴파일링을 한다.

출처


import 키워드

개발자가 직접 A to Z를 작성하지 않는 이상 외부 라이브러리를 사용하곤 하는데, 이렇게 외부 라이브러리를 가져올때 사용하는 키워드가 import이다.

자바의 코드는 아래의 3가지로 구성된다.

  • package
  • import
  • 클래스 선언

bulk import

패키지 경로가 같은 라이브러리가 있다면, Asterisk(*)으로 중복을 처리할 수 있다.

1
2
import java.util.Calendar;
import java.util.Date;

위의 패키지는 아래처럼 정리할 수도 있다.

1
import java.util.*;

이렇게 하면 java.util.의 클래스를 전부 가져온다. 그러나 아래의 코드를 라이브러리를 불러오지 못한다.

1
import java.*;

*는 작성된 계층의 클래스를 불러올뿐, 하위 클래스를 불러오는데 사용할 수는 없다.

import static 문

import 패키지를 static 키워드로 불러오면, 패키지를 작성하지 않고도 클래스의 메서드를 호출할 수 있다. 아래의 코드를 보자.

1
2
3
4
5
class StudyHalle {
public static void main(String[] args){
System.out.println("Hello world.");
}
}

위의 코드에서 import static 키워드를 사용해서 바꿔보았다.

1
2
3
4
5
6
7
import static java.lang.System.*;

class StudyHalle {
public static void main(String[] args){
out.println("Hello world.");
}
}

패키지 static 키워드를 붙여서 import하면, 사용하면 System 클래스를 작성하지 않고도 바로 사용할 수 있다.


클래스패스

클래스패스(CLASSPATH)란, JVM이 프로그램을 실행할 때, class 파일을 찾는데 기준이 되는 파일의 경로를 말한다.

컴파일 이후 변환된 바이트코드를 런타임에 실행할때, 바이트코드에 포함된 명령을 실행해야하는데, 이 때 CLASSPATH를 통해서 찾는다고 한다.

클래스 파일을 지정하는 방법은 두가지가 있다.

출처 - 알쓸신잡 - 자바 클래스패스(CLASSPATH)란?


CLASSPATH 환경변수

컴퓨터 시스템 변수 설정을 통해 CLASSPATH 환경변수를 지정하는 방식이다.

JVM이 시작되면, JVM의 클래스 로더가 환경변수를 호출하는데, 이 환경변수에 설정된 CLASSPATH를 따라서 해당 클래스들을 먼저 클래스 로더가 메모리로 로딩한다.

맥에서 자바 CLASSPATH를 환경변수로 지정해보겠다.

iTerm에서 아래의 명령어를 입력하면 내 컴퓨터에 설치된 JDK 목록이 출력된다.

1
/usr/libexec/java_home -V

![](/Users/Andy/Desktop/draft/Screen Shot 2021-02-15 at 12.08.26 AM.png)

오라클에서 JDK 11.0.10을 설치했는데, 이걸로 JDK CLASSPATH를 지정하려고 한다.

1
vim ~/.bash_profile

홈 디렉토리 하위에 .bash_profile 이라는 이름의 파일을 생성했다.

1
2
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-11.0.10/Contents/Home
export PATH=${PATH}:$JAVA_HOME/bin

여기서 JAVA_HOME 을 변수로 지정하고, 이 JAVA_HOME에 변경하고자하는 JDK의 CLASSPATH를 작성한다. 그리고 이 JAVA_HOME을 변수로 이용해서 PATH로 지정을 하는 명령어이다.

1
source ~/.bash_profile

마지막으로 위 명령어를 iTerm에서 입력해야 실제로 반영이되어 java -version 에서 바뀐 JDK버전이 출력된다.

그러나 여기까지만 하면, iTerm을 종료하고 재실행했을때, jdk가 다시 이전으로 돌아간걸 확인할 수 있다. 현재 맥은 zsh라는 쉘이 적용되어 있는데, 이 zsh은 .zshrc 의 설정을 따른다고 한다. 따라서 이 zshrc를 수정해야만 최종적으로 jdk를 변경한걸 적용할 수 있다.

1
vim ~/.zshrc
1
2
3
source ~/.bash_profile
source ~/.bashrc
source ~/profile

이젠 iTerm을 종료하고 다시켜더라도 jdk 버전이 변경된걸 확인할 수 있다.

출처 : 코딩하는 다람쥐 - Mac에서 자바 path 및 환경변수 설정하기


-classpath 옵션

-classpath 옵션키워드를 사용하면 환경설정을 하지않고도 또는 임의로 CLASSPATH를 지정하는것이 가능하다.

DevAndy라는 클래스를 실행하면서 여기에 필요한 클래스가 EngClasses, KorClasses가 있다면, 이 때 실행하는 명령어는 다음과 같다.

1
javac -classpath /classes/EngClasses;/classes/KorClasses DevAndy.java

두개의 CLASSPATH가 필요했기 때문에 각각의 CLASSPATH를 ;로 구분했다.

출처 : killog - 7주차 과제 : 패키지


접근지시자

클래스나 메서드에 작성하던 접근제한자에 대한 테이블이다. Row엔 접근가능 범위를, Column엔 접근 가능여부를 작성했다.

접근 제한자 적용가능 대상 해당 클래스 같은 패키지 자식 클래스(extends/implements) 외부 클래스(import)
public 클래스, 생성자, 메서드, 필드 O O O O
protected 생성자, 메서드, 필드 O O O X
default 클래스, 생성자, 메서드, 필드 O O X X
private 생성자, 메서드, 필드 O X X X