본문 바로가기
자바/스터디

[자바 스터디] 7주차 과제 - 패키지

by jeonghaemin 2021. 1. 2.
728x90

본 게시글은 백기선 님의 live-study 과제를 수행하면서 작성한 글입니다.

목표

자바의 패키지에 대해 학습하세요.

학습할 것 (필수)

  • package 키워드
  • import 키워드
  • 클래스패스
  • CLASSPATH 환경변수
  • classpath 옵션
  • 접근지시자

package

패키지란?

  • 패키지는 클래스의 묶음이다.
  • 서로 관련된 클래스, 인터페이스를 묶어서 효율적으로 관리할 수 있다.
  • 클래스가 하나의 물리적인 파일인 것처럼 패키지는 물리적인 디렉토리 경로이다.

예를 들어 String 클래스의 경우 패키지 이름까지를 포함한 풀네임은 java.lang.String인데 이것은 즉,

String클래스는 java/lang/String.java의 경로에 위치하고 있다는 것이다.

실제로 jdk디렉토리/Contents/Home/lib/src.zip 파일의 압축을 풀어 보면 java.base/java/lang/String.java 경로로 String.java파일이 위치하고 있는 것을 볼 수 있다.

패키지 선언 방법

  • 클래스나 인터페이스 소스 파일의 맨 윗 줄에 'package 패키지명;' 을 적어주면 된다.
  • 패키지명은 대소문자를 모두 허용하지만, 클래스명과 구분하기 위해 소문자로 적어주는 것을 원칙으로 한다.
  • 패키지를 지정하지 않으면 자바에서 기본으로 제공하는 '이름 없는 패키지(unnamed package)'에 포함되게 된다.

import

소스코드를 작성할 때 다른 패키지의 클래스를 사용하려면 패키지 명을 포함한 풀네임을 클래스 이름으로 사용해야 한다.

java.util.List<Integer> list = new java.util.ArrayList<Integer>();

하지만 코드를 작성하기 전에 import 키워드로 사용하고자 하는 클래스의 패키지를 알려주면 소스코드에서 사용되는 클래스의 패키지명을 생략할 수 있다.

package org.example;

import java.util.ArrayList;
import java.util.List;

public class App 
{
    List<Integer> list = new ArrayList<Integer>();
}

import 키워드의 위치는 package문과 class선언의 사이에 위치해야 한다.

같은 패키지의 여러 클래스를 사용할 경우 한 줄로 축약할 수 있다

주의할 점은 클래스 이름을 대신하는 것이지 하위 패키지까지를 포함하지는 않는다.

import java.util.*;
import java.time.*;

//위 import문을 다음과 같이 축약할 수 없다.
import java.*;

String이나 System과 같은 java.lang패키지의 클래스들은 import문이 없더라도 패키지명을 명시하지않아도되는데 그 이유는 모든 소스파일에는 묵시적으로 'import.java.lang.*'이 삽입되어 있기 때문이다.

java.lang패키지는 자주 사용되는 중요한 클래스들이 속한 패키지이기 때문에 개발자가 import를 생략할 수 있도록 한 것이다.

static import

import를 사용하여 패키지명을 생략했듯이, static import를 사용하면 static 멤버를 호출할 때 클래스 이름을 생략할 수 있다.

모든 멤버가 static으로 구성되어있는 Math 클래스의 random() 메서드를 예로 들어보자.

public class App 
{
    public static void main( String[] args )
    {
        double random = Math.random();
    }
}

static import를 사용하면 다음과 같이 클래스명을 생략할 수 있다.

import static java.lang.Math.random;

public class App 
{
    public static void main( String[] args )
    {
        double random = random();
    }
}

클래스패스

클래스패스란 말 그대로 클래스 파일을 찾기 위한 경로이다. JVM이 자바 프로그램을 실행할 때 .class 파일을 찾는 기준이 되는 경로가 바로 클래스패스이다.

클래스 패스 지정 방법

  1. 클래스패스 환경변수 설정
  2. 자바 런타임에-classpath 옵션 사용

환경변수 설정(MacOS 기준)

현재 사용 중인 쉘의 종류에 따라 Bash를 사용 시 ~/ .bash_profile, zsh 사용시 ~/.zshrc 파일을 열어준다.

어떤 쉘을 사용하는지 모른다면 다음 명령어를 통해 확인할 수 있다.

echo $SHELL

에디터로 파일을 열어 CLASSPATH 환경변수를 입력해준다.

export CLASSPATH=.:$JAVA_HOME/lib/tools.jar

설정 파일을 새로 고침 해준다.

source ~/.zshrc 

환경변수가 제대로 설정되었는지 확인한다.

echo $CLASSPATH

자바 런타임에 -classpath 옵션 사용

런타임 시에 classpath 옵션을 사용해 경로를 지정해주면 된다

java -classpath "필요한 클래스 파일들의 경로" Hello.class

참조할 클래스 파일의 경로가 여러 개라면 "경로1; 경로2" 와 같이 ; 를 구분자로 사용하여 적어주면 된다.

java Hello

또는

java -classpath /생략/java-project Hello

로 실행을 하면 정상적으로 실행이 된다. 이를 통해 별도로 classpath옵션을 지정하지 않으면 현재 경로를 classpath로 사용하는 것을 알 수 있다.

java -classpath /생략/java-project/temp Hello

그런데 만약 다음과 같이 Hello.class 파일이 없는 경로를 classpath로지정해서 실행하면 클래스를 찾을 수 없다는 에러가 발생한다.

접근 지시자

접근 지시자를 사용하여 클래스와 멤버의 접근 범위를 설정할 수 있다.

  • public : 자유롭게 접근 가능.
  • (default) : 같은 패키지 내에서 접근 가능, 접근제어자가 명시되어있지 않으면 default이다.
  • protected : 같은 패키지 내에 있거나, 상속받는 경우 접근 가능.
  • private : 같은 클래스에서만 접근 가능.
클래스 사용가능한 접근 지시자
클래스 public, default
메서드 public, protected, default, private
멤버변수 public, protected, default, private
지역변수 없음

접근 지시자를 이용한 캡슐화

클래스나 멤버에 접근 지시자를 사용하는 이유는 외부로부터 데이터를 보호하거나 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위함인데 이것은 객체 지향의 캡슐화에 해당하는 것이다.

참고

댓글