[Live Study] #7 패키지

Jihoon Oh·2021년 1월 30일
0

Live Study

목록 보기
7/13
post-thumbnail

목표

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

학습할 것 (필수)

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

package 키워드

자바의 패키지는 파일이 많아져서 관리하기 힘들면 키워드 별로 폴더를 만들어서 파일을 관리하는 것처럼 비슷한 성격의 자바 클래스들을 모아 넣는 자바의 폴더 또는 디렉토리라고 볼 수 있다. 패키지 내부의 클래스의 맨 첫줄에 package 키워드와 함께 패키지 경로를 써서 패키지를 선언하며, 클래스의 폴더 이름과 디렉토리 이름은 같아야 한다. javaproject.package.subpackage 처럼 .을 사용해 서브패키지(하위 패키지)를 만들고 표시할 수 있다.

자바에서 기본적으로 제공하는 클래스들도 패키지에 속해 있다. 예를 들어 자바에서 제공하는 레퍼런스 타입의 String 클래스 같은 경우는 java.lang 패키지에 들어있고, List 클래스 같은 경우에는 java.util 패키지에 들어있다.

일반적으로 패키지 이름 규칙은 다음과 같다.

패키지 이름내용
java자바에서 기본으로 제공하는 패키지
javax자바 확장 패키지
org오픈소스에서 제공하는 패키지
com영리단체에서 제공하는 패키지

또한 자바 패키지 이름에는 자바의 예약어를 사용할 수 없으며 클래스 이름과는 다르게 패키지 이름에는 반드시 소문자를 사용하여야 한다. 또한 패키지는 네임스페이스 역할을 하기 때문에 서로 다른 패키지 안에서는 같은 이름의 클래스를 선언할 수 있다. 예를 들어, List 클래스는 java.util에 있지만, java.awt에도 똑같은 List 클래스가 존재한다. 이렇게 다른 두 개의 클래스는 패키지명까지 명시하므로써 구분할 수 있다.

import 키워드

같은 패키지 안에서는 패키지명을 명시하지 않더라도 클래스를 찾아서 쓸 수 있다. 예를들어 example.test 패키지 안에 Test1 클래스와 Test2 클래스가 있다면, Test1 클래스 안에서 Test2 클래스를 사용하려면 특별한 조건 없이 Test2 클래스의 인스턴스를 만들어서 사용해 주면 된다.

하지만 다른 패키지 안에 있는 클래스들을 사용하려면, import 키워드를 사용해 주어야 한다. 리스트를 사용하기 위해 List 클래스를 선언했다고 가정하자. 그런데 이때 정상적으로 컴파일 되지 않고 오류가 발생하거나, IDE상에서 빨간 밑줄이 그어져 있을 것이다. 이는 해당 패키지 내에 List라는 클래스가 존재하지 않기 때문이다.

또한 앞서 설명했듯이 List 클래스는 java.util에도 존재하고, java.awt에도 존재한다. 우리가 사용하려는 List가 어떤 List인지 컴파일러가 알게 하기 위해서 클래스 파일의 상단에 import 키워드를 통해 명시해 주어야 한다.

우리가 사용하려는 클래스는 java.util 패키지의 List이므로

import java.util.List;

를 적어주면 해당 java 파일 내에서 사용하는 List 클래스는 자동적으로 java.util 패키지 안의 List로 인식된다.

그런데, 같은 패키지 안에 여러 클래스를 사용할 때, 모든 클래스를 다 일일히 import 해주는 것은 코드의 길이도 늘어나고, 귀찮은 일이 될 수도 있다. 이럴 때 패키지 자체를 import할 수 있는데, 와일드카드 * 를 사용해서 import 하면 된다.

import java.util.*;

위와 같이 import 하게 되면 java.util 패키지 내에 있는 모든 클래스를 import 한 것과 같은 효과를 낸다.

클래스에 static 클래스가 있듯이, import에도 static import가 존재한다. JDK 1.5부터 제공되는 기능이며, static이 붙은 메소드는 해당 메소드가 들어있는 클래스를 인스턴스화 하지 않고 바로 사용할 수 있다. 예를 들어, java.lang 패키지의 Math클래스의 abs() 메소드는

int i = Math.abs(-3);

처럼 Math 클래스를 import만 해주면 Math 클래스의 인스턴스를 만들지 않고 사용할 수 있다. 그런데, static import를 사용하면 더욱 쉽게 사용할 수 있다.

import static java.lang.Math.abs;

int i = abs(-3);

static import는 static 메소드 뿐 아니라 static 멤버 변수에도 사용이 가능하다. 예를 들어 Math 클래스의 static 멤버 변수 PI는

import static java.lang.Math.PI;

System.out.println(PI); // 원주율이 출력된다.

와 같이 사용할 수 있다.

* java.lang

static import를 설명해면서 Math.abs를 설명할 때, static import가 아닌 그냥

import java.lang.Math;

는 없었다. 또한 생각해보면, 우리가 수 없이 String 자료형을 쓰면서 한번도 java.lang.String을 import 해본 적이 없다. 그 이유는 java.lang은 import를 할 필요가 없는 패키지이기 때문이다. java.lang 패키지는 가장 기본적인 클래스들이 모여있는 패키지로, import 없이 자동적으로 프로그램에 포함된다. java.lang 패키지 않에는 다음과 같은 클래스들이 존재한다.

String, StringBuffer
Process, Runtime, Thread
Math, StrictMath
Exception Throwable, Error
Package, Class, ClassLoader
Wrapper, System, Stream

클래스패스

말 그대로 클래스를 찾기 위한 경로다. 조금 더 풀어 말하자면 JVM이나 자바 컴파일러에 사용자 지정 클래스와 패키지의 위치를 지정해주는 값이고, 쉽게 말하자면 자바가 사용할 클래스의 위치가 어디인지를 지정해주는 값이다.

자바 소스 코드를 컴파일 하면 바이트 코드인 .class 파일로 바뀌게 된다. jre를 통해 이 .class 파일에 포함된 명령을 실행하려면 이 파일을 찾을 수 있어야 하는데, 이때 클래스패스에 지정된 경로를 사용한다.

클래스패스에는

  • /export/home/username/java/classes와 같은 디렉토리
  • myclasses.zip과 같은 zip 파일
  • myclasses.jar와 같은 jar(자바 아카이브) 파일

과 같은 세 가지 유형을 지정할 수 있고, 콜론(:)을 통해 구분한다. 예를 들어 위 세가지 유형을 모두 지정하면

/export/home/username/java/classes:/export/home/username/java/classes/util.zip:/export/home/username/java/classes/checkers.jar

와 같이 사용할 수 있다.

클래스패스는 기본적으로 패키지에 포함되어 있지 않은 자바 소스를 컴파일 할 때 사용하게 되며, 클래스가 있는 디렉토리에서 실행을 할 때는 지정할 필요가 없다. 클래스패스를 지정하는 방법에는 CLASSPATH 환경변수를 사용하는 방법과 런타임에 -classpath 옵션을 사용하는 방법이 있다.

-classpath 옵션

터미널에서 자바를 컴파일 할 때는 다음과 같은 명령어를 사용한다.

javac <options> <source files>

여기서 source files 부분에는 당연히 컴파일 할 자바 소스 파일의 경로가 들어간다. 이 때 위에서 설명했듯이 해당 소스 파일이 외부 클래스를 참조하고 있다면 클래스패스를 지정해줘야 하는데, options 부분에서 클래스패스를 지정한다.

클래스패스를 지정하는 옵션은 -classpath 또는 줄여서 -cp 명령어이며, 그 뒤에 클래스패스를 적어서 경로를 지정해준다. 예를 들어 클래스들이 C:\java\class 경로에 존재한다면,

javac -classpath C:\java\class c:\java\helloworld.java

와 같이 지정해줄 수 있다. 만약 클래스패스를 여러개 지정해야 한다면, 세미콜론(;)을 통해 구분할 수 있다.

CLASSPATH 환경변수

환경변수는 운영체제에 저장하는 변수로, 자바의 환경변수로는 JAVA_HOME과 CLASSPATH가 있고, JVM은 이들 환경변수를 참고해서 동작한다.

Windows 10 기준으로, 환경변수는 제어판 - 시스템 및 보안 - 시스템 - 고급 시스템 설정 - 고급 탭 - 환경 변수 에 들어가서 설정할 수 있다. JAVA_HOME 변수에 자신의 컴퓨터에 설치된 jdk의 경로를 입력하고, CLASSPATH 변수에는 %JAVA_HOME%\lib 경로를 설정해주면 컴퓨터에 JDK의 클래스패스를 지정할 수 있다.

접근지시자

접근지시자 또는 접근제어자는 클래스, 메소드, 멤버 변수 등을 선언할 때 사용하며, 해당 클래스, 메소드, 멤버 변수 등에 접근할 수 있는 허용 범위를 지정한다.

자바의 접근지시자로는 public, private, protected 총 3개가 존재하며, 아무것도 붙이지 않은 default 상태도 존재한다.

지시자클래스 내부동일 패키지상속받은 클래스그 외 영역
privateOXXX
defaultOOXX
protectedOOOX
publicOOOO

public으로 선언되면 어디에서나 접근할 수 있고, private로 선언되면 해당 클래스 내부에서 밖에 접근할 수 없어 보통 멤버 변수를 선언하는데 많이 사용한다.

protected는 상대적으로 public과 private에 비해서 많이 쓰이지는 않는데, protected로 선언되면 해당 클래스 내부나 동일 패키지 내부 뿐 아니라 해당 클래스를 상속받은 클래스에서도 사용할 수 있다. 예를 들어,

public class Person {
    protected String name;
    protected int age;
}

라는 클래스를 선언했다면, Person 클래스 이외의 영역에서 Person의 name과 age에 접근하는 것은 불가능하지만, Person을 상속받은 클래스 Student가 있다면 Student에서는 접근할 수 있다.

profile
Backend Developeer

0개의 댓글