본문 바로가기
java-liveStudy

7주차. 패키지

by 에드박 2021. 1. 1.

목표

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

학습할 것 (필수)

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

pakage키워드

package 란 우리가 기본적으로 사용하는 컴퓨터의 폴더와 같은 개념입니다..

 

우리는 폴더를 사용해서 뒤죽박죽인 파일들을 각각의 주제에 맞게 분류하여 정리할 수 있습니다.

 

예를들어 사진을 엄청 찍어놓고 날짜별로 분류한다던지 사람사진, 배경사진, 사물사진 등으로 폴더명을 지어 보기 쉽게 정리 할 수 있습니다.

제목만 보더라도 내용물에 어떤것들이 들어있을지 알게 되는 것입니다.

 

이와같이 자바에서도 클래스를 구분짓는 폴더역할을 하는것이 pakage 입니다.

 

pakage 는 소스의 가장 첫줄에 위치하며 클래스 파일 안에 하나의 pakage 만 선언할 수 있습니다.

 

만약 pakage 선언이 없다면 default pakage 에 속한것으로 취급하며 default pakage 는 어떤 패키지에도 속하지 않는 상태를 말합니다.

 

 

패키지 이름 지정 규칙

패키지 시작이름 내용
java 자바 기본 패키지(java vendor 개발)
javax 자바 확장 패키지(java vendor 개발)
org 일반적으로 비영리 단체 (오픈소스 패키지)
com 일반적으로 영리 단체(회사)

출처 : kils-log-of-develop.tistory.com/430

 

 

패키지 이름을 짓는데는 몇가지 규칙이 있습니다.

  • 자바의 예약어(int, static, boolean, private 등등)은 사용할 수 없습니다.
  • 패키지 이름은 모두 소문자여야 합니다.(대문자도 사용 가능 하지만 자바 개발자분들은 패키지에 소문자만을 사용하고있습니다)

 


import 키워드

import 키워드는 다른 패키지에 있는 클래스를 사용하고 할 때 사용합니다.

 

원래 다른 패키지에 있는 클래스를 사용하려면 클래스 앞에 패키지명을 모두 추가해 줘야 합니다.

 

예를들어 demo/test/Study.class 다른 패키지에서 사용하려면 demo.test.Study 와 같은 방식으로 코드를 사용해야 합니다.

 

import 키워드를 사용하지 않고 다른 패키지의 클래스 사용하기

import 키워드를 사용하면 매번 다른 패키지의 클래스를 사용할 때 마다 패키지 경로를 장황하게 쓸 필요가 없습니다.

 

import 를 사용해서 클래스 이름만으로 다른 패키지의 클래스를 사용할 수 있습니다.

 

import 를 하지않아도 되는 패키지

  • java.lang 패키지(System.out.println(), String)
  • 같은 패키지

클래스패스

 

클래스를 찾기 위한 경로를 말합니다.

 

좀더 자바의 관점에서 말한다면 JVM 프로그램을 실행할 , 클래스 파일을 찾는 기준이 되는 파일 경로를 말합니다

 

소스 코드(.java 파일) 컴파일하면 소스 코드가바이트 코드”(바이너리 형태의  .class 파일) 변환됩니다.

Java runtime(java 또는 jre)으로 .class 파일에 포함된 명령을 실행하려면, 먼저 파일을 찾을 있어야 합니다.

이 때 .class 파일을 찾을 때 classpath에 지정된 경로를 사용합니다.

 

classpath는 .class 파일이 포함된 디렉토리와 파일을 콜론(;)으로 구분한 목록입니다.

찾으려는 클래스 코드가 포함된 .class 파일을 찾으면 첫 번째로 찾은 파일을 사용합니다.

 

classpath를 지정할 수 있는 두 가지 방법이 있습니다.

  • 환경 변수 CLASSPATH 사용하는 방법
  • Java runtime -classpath 옵션을 사용하는 방법   

 

classpath에 사용할 수 있는 값

앞에서 설명한 대로 classpath는 콜론(:)으로 구분된 디렉토리 및 파일 목록이다. 다음 세가지 유형의 파일과 디렉토리를 classpath에 지정할 수 있다. ( 윈도우 운영체제에서는 세미콜론(;)으로 구분합니다.)

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

위 세가지 유형을 모두 사용하면 다음과 같이 지정할 수 있습니다.

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

.zip 파일과 .jar 파일은 하나의 아카이브로 압축된 자바 클래스 파일 세트를 말합니다.

 

classes.zip 파일

classes.zip 파일은 1.1 기반 Java Runtime 의 표준 클래스가 모두 포함된 아카이브 파일입니다. 예를 들어, java.awt, java.io, java.net 등의 패키지에 있는 클래스가 모두 여기에 포함되어 있습니다.

JDK 1.1 이전에는 classes.zip 파일을 classpath에 포함시켜야 했습니다. 

그러나 1.1 버전부터는 classes.zip 파일을 plasspath에 포함시키면 안됩니다. Java 가 자동으로 classes.zip 파일을 찾을 수 있기 때문입니다. classes.zip 파일을 classpath에 지정하면 지정하지 않을 때보다 더 많은 문제가 발생합니다. 

 

일반적으로 다음과 같은 문제가 발생합니다.

JDK 1.1.4 설치할 포함된 classes.zip 파일을 classpath 추가한다고 가정합니다.

classes.zip 파일을 .cshrc 같은 시작 파일 하나에 추가하고 나서 classes.zip 파일의 경로를 지정한 것을 기억하지 못합니다. 그러나 jdk 사용하면 경로에서 이전의 classes.zip 파일을 먼저 찾게 되기 때문에 이전의 클래스가 사용됩니다. 따라서 java 프로그램은 실행되지 않고 문제와 관련이 없는 오류 메시지가 나오게됩니다.

 

rt.jar 파일

JRE JDK 사이에는 차이가 있습니다. JRE JDK 중에서 java 프로그램을 실행하는 프로그램만 포함된 환경입니다. 따라서 JRE classes.zip 파일에서 클래스를 찾지 않습니다. 대신 rt.jar 파일을 사용합니다.

 

rt.jar 파일에는 classes.zip과 동일한 클래스가 모두 포함되어 있고, 아카이브 형식과 이름만 다른 것을 사용합니다. Java 1.2 발표되면서 classes.zip 파일은 없어졌습니다. 대신 JDK JRE 모두 rt.jar 파일을 사용합니다. rt.jar 파일을 classpath 지정해야 하는가에 대해서는 classes.zip 파일과 동일한 규칙이 적용됩니다. , 지정할 필요가 없습니다.


CLASSPATH 환경변수

환경변수는 운영체제에 지정하는 변수로 자바 가상머신과 같은 애플리케이션들은 환경변수의 값을 참고해서 동작하게 됩니다. 

 

자바는 클래스 패스로 환경변수 CLASSPATH를 사용하는데 이 값을 지정하면 실행할 때마다 -classpath 옵션을 사용하지 않아도 되기 때문에 편리합니다. 하지만 운영체제를 변경하면 환경변수는 사라지기 때문에 이식성 면에서는 단점이 있습니다.

 

JVM 시작될 JVM 클래스 로더는 CLASSPATH 환경 변수를 호출합니다. 그래서 환경 변수에 설정되어 있는 디렉토리가 호출되면 디렉토리에 있는 클래스들을 먼저 JVM 로드합니다. 그러므로 CLASSPATH 환경 변수에는 필수 클래스들이 위치한 디렉토리를 등록하도록 합니다.

 

 

- 윈도우에서 Java 환경 변수 설정

https://macchiato.tistory.com/9 윈도우에서 환경 변수 설정

 

- 맥에서 Java 환경 변수 설정

https://whitepaek.tistory.com/28 mac에서 환경변수 설정

 


-classpath 옵션

옵션 -classpath는 자바를 실행할 때 사용할 클래스들의 위치를 가상머신에게 알려주는 역할을 합니다.

 

현재 디렉토리에서 하위 디렉토리 lib 에 있는 Hello.class 파일을 사용하려면 다음과 같이 할 수 있습니다.

 

java -classpath .:lib Hello

 

. 은 현재 디렉토리를 의미합니다.

:은 경로와 경로를 구분하는 구분자 역할을 합니다. (문자 사이의 ',' 같은 역할이라 생각하면 됩니다.)

(윈도우 운영체제에서는 세미콜론[;] 이 구분자 역할을 합니다.)

.. 은 현재 디렉토리의 상위 디렉토리를 말합니다.

 

따라서 위의 경로를 해석하자면 [현재 디렉토리와 lib 디렉토리에 있는 Hello.class 파일을 찾는다] 라는 뜻입니다.


접근지시자

접근 지시자는 멤버 또는 클래스에 사용되어, 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 합니다.

 

접근 지시자가 지정되어 있지 않다면 접근지시자가 default 임을 의미합니다.

 

접근 지시자가 사용될 수 있는 곳

  • 클래스
  • 멤버변수
  • 메서드
  • 생성자
지역 변수에는 접근 지시자 사용이 불가능 합니다.

 

접근 지시자의 종류와 권한

  • public : 접근 제한이 전혀 없음
  • protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능함
  • default : 같은 패키지 내에서만 접근이 가능
  • private 같은 클래스 내에서만 접근이 가능
지시자 같은 클래스 같은 패키지 자손 클래스 전체
public 가능 가능 가능 가능
protected 가능 가능 가능 불가능
default 가능 가능 불가능 불가능
private 가능 불가능 불가능 불가능

 

접근 지시자를 사용하는 이유

  • 외부로 부터 데이터를 보호하기 위해서
  • 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서
  • 데이터가 유효한 값을 유지하도록, 또는 비밀번호와 같은 데이터를 외부에서 함부로 변경하지 못하도록 하기 위해서는 외부로부터 접근을 제한하는것이 필요

생성자의 접근 지시자

생성자에 접근 지시자를 사용함으로써 인스턴스의 생성을 제한할 수 있습니다. 이를 통해 싱글톤 객체(하나의 객체만을 생성해서 사용함)를 사용할 수 있습니다.

 

생성자의 접근 지시자를 private 지정하면, 외부에서 생성자에 접근할 수 없으므로 인스턴스를 생성할 수 없게됩니다.

그래도 클래스 내부에서는 인스턴스를 생성할 수 있습니다.

 

class Singleton {
    private Singleton() {
        ....
    }
}

 

대신 인스턴스를 생성해서 반환해주는 public 메서드를 제공함으로써 외부에서 이 클래스의 인스턴스를 사용하도록 할 수 있습니다.

이 메서드는 public 인 동시에 static 이어야합니다.

 

class Singleton {
    private static Singleton s = new Singleton();

    private Singleton() {
        ....
    }

    // 인스턴스를 생성하지 않고도 호출할 수 있어야 하므로 static 이어야 합니다.
    public static Singleton getInstance() {
        return s;
    }
}

 


지시자의 조합

대상 사용가능한 지시자
클래스 public, (default), final, abstract
메서드 모든 접근 지시자, final, abstract, static
멤버변수 모든 접근 지시자, final, static
지역변수 final

 

지시자를 조합해서 사용할 때 주의해야 할 사항

  • 메서드에 static 과 abstract를 함께 사용할 수 없습니다.
    static 메서드는 몸통이 있는 메서드에만 사용할 수 있기 때문입니다.
  • 클래스에 abstract와 final을 동시에 사용할 수 없습니다.
    클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고 abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문입니다.
  • abstract메서드의 접근 제어자가 private 일 수 없습니다.
    abstract메서드는 자손 클래스에서 구현해주어야 하는데 접근 제어자가 pricate이면, 자손 클래스에서 접근할 수 없기 때문입니다.
  • 메서드에 private와 final을 같이 사용할 필요는 없습니다.
    접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문입니다. 이 둘 중 하나만 사용해도 의미가 충분합니다.

 


참고 문헌

 

자바의 정석

 

effectivesquid.tistory.com/entry/%EC%9E%90%EB%B0%94-%ED%81%B4%EB%9E%98%EC%8A%A4%ED%8C%A8%EC%8A%A4classpath%EB%9E%80

 

opentutorials.org/course/1223/5527

 

kils-log-of-develop.tistory.com/430

 

macchiato.tistory.com/9

 

blog.opid.kr/62

 

 

'java-liveStudy' 카테고리의 다른 글

9주차 과제. 예외  (0) 2021.01.16
8주차. 인터페이스  (0) 2021.01.09
6주차 과제. 상속  (0) 2020.12.25
5주차. 과제  (0) 2020.12.17
5주차. 클래스  (0) 2020.12.16

댓글