Programming/JAVA

패키지란?

잇나우 2021. 1. 21. 00:14
반응형

패키지

  • 클래스와 인터페이스등을 구분 짓는 폴더 개념과 비슷
  • 패키지의 물리적인 형태는 파일 시스템의 폴더이다.
  • 패키지는 클래스를 유일하게 만들어주는 식별자 역할을 한다.
  • 클래스의 완전한 이름은 패키지 + 클래스명 이며 FQCN(Fully Qualified Class Name) 이라고 한다.
    예로 String 클래스의 패키지는 java.lang이며 FQCN은 java.lang.String이다.
  • 패키지가 상, 하위로 구분되어 잇다면 .를 사용하여 표현한다.
  • 패키지의 이름은 java로 시작하면 안된다.
  • 파일 시스템의 디렉토리와 비슷한 역할이기 때문에 패키지 명과 동일한 디렉토리 구조를 따라야 한다.

패키지 이름 명명 규칙

패키지 시작이름 내용
java 자바 기본 패키지 (Java vendor 개발)
javax 자바 확장 패키지 (Java vendor 개발)
org 일반적으로 비영리단체 (오픈소스) 패키지
com 일반적으로 영리단체(회사) 패키지
  • 패키지 이름은 소문자여야 한다.
  • 자바의 예약어는 사용하면 안된다.
  • 개발 패키지 표준은 정하는 것에 따라 지정하면 된다.

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

자바는 개발자들이 사용할 수 있도록 여러 많은 패키지 및 클래스를 제공한다. 가장 자주 쓰이는 패키지로는 java.langjava.util이 있다.
java.lang은 자주 사용하는 패키지이긴 하지만 import하지 않아도 사용할 수 있다. 자바에서 java.lang 패키지는 아주 기본적인 것들이기 때문에 import하지 않아도 자바가 알아서 java.lang의 클래스를 불러온다.

import java.lang.String;
import java.lang.System;

public class Main {
    public static void main(String[] args) {
        String str = "this is from java.lang.String";
        System.out.println(str);
    }
}
  • java.lang
    language support 클래스들을 포함하는 패키지
    1. primitive type이나 수학 연산의 정의가 되는 클래스들
    2. 자동으로 import가 되기 때문에 바로 사용할 수 있다.
  • java.io
    입출력 기능을 지원하는 클래스들을 포함하는 패키지
  • java.util
    자료구조 구현을 위한 유틸리티 클래스를 포함하는 패키지
  • java.applet
    Applets을 생성하기 위한 클래스들을 포함하는 패키지
  • java.awt
    GUI 컴포넌트를 구현하기 위한 클래스들을 포함하는 패키지
  • java.net
    네트워킹 기능을 지원하기 위한 클래스들을 포함하는 패키지

import 키워드

같은 패키지에 있는 클래스는 조건 없이 서로 사용할 수 있지만, 다른 패키지에 있는 클래스를 사용하려면 2가지 방법 중 하나를 선택해서 사용해야한다.

  1. 패키지와 클래스 모두 명시, 즉 FQCN을 이용하는 방법

    package com.birthday
    
    public class Present {
       com.cellphone.Iphone iphone = new com.cellphone.Iphone();
    
       // com.cellphone.Iphone : 데이터 타입
       // iphone : 필드명
       // new com.cellphone.Iphone() : 객체 생성
    }
  2. import 문을 사용하는 방법

    package com.birthday
    
    import com.cellphone.Iphone;
    // import com.cellphone.*     // cellphone 하위의 모든 클래스 import
    
    public class Present {
       Iphone iphone = new iphone();
    }
  • import 문은 패키지 선언과 클래스 선언 사이에 선언된다.
  • 패키지에 있는 여러개의 클래스를 사용한다면 *이용 하면 패키지 하위에 있는 클래스들을 import한 것과 같다
  • import 문의 갯수 제한은 없다.
  • import 문으로 지정된 패키지의 하위 패키지는 import 대상이 아니다. 만약 하위 패키지를 사용하고 싶으면 import 문을 하나 더 작성해야 한다.

    패키지가 다르지만 클래스 이름이 똑같고 클래스가 모두 import된 경우 자바 컴파일러는 어떤 패키지에서 클래스를 로딩할 지 결정할 수 없기 때문에 컴파일 에러가 발생한다. 정확한 패키지 이름 전체를 기술해주어야 한다.

import com.cellphone.Iphone;
import com.applephone.Iphone;

public class Present {
    com.cellphone.Iphone smartPhone = new com.cellphone.Iphone();
    com.applephone.Iphone applePhone = new com.applephone.Iphone();
}

static import

일반적인 import와 다르게 메소드나 변수를 패키지, 클래스명 없이 접근가능하게 해준다.

import static java.lang.System.*;

public static void main(String[] args) {
    out.println("text");
}

현재 코드에 import의 static을 빼면 컴파일 에러가 발생한다.
static import를 사용하면 매우 편리해진다. 특히 테스트 프레임워크인 Junit을 사용하다보면 static import의 다양한 예를 볼 수 있다.

// static import를 적용하지 않은 예
@Test
public void nonStaticImport() {
    Assert.assertThat(1, CoreMatchers.is(1));
}

// static import를 적용한 예
@Test
public void staticImport() {
    assertThat(1, is(1));
}

static import를 사용하게 되면 코드를 읽을 때, 위 코드와 같이 That ~ is ~ 로만 읽어서 코드의 의도를 쉽게 파악하고 이해하기가 쉽다.

접근 제어자 (Access Modifier)

접근 제어자는 클래스, 메서드, 인스턴스 및 클래스 변수를 선언할 때 사용한다. 객체 생성을 막기 위해 생성자를 호출하지 못하게 하거나, 객체의 특정 데이터를 보호하기 위해 해당 필드에 접근하지 못하게 하거나, 특정 메서드를 호출할 수 없도록 제한한다. 자바에서는 4가지 접근 제어자가 있다.

  • public
    모든 패키지에서 아무런 제한없이 호출 할 수 있다.
    보통 생성자 또는 필드, 메서드가 public이라면 클래스도 pulbic 접근 제어자를 가진다.
  • protected
    같은 패키지에 속하는 클래스에서 호출할 수 있다. 하지만 다른 패키지에 속하지만 해당 클래스를 상속하고 있다면 호출할 수 있다.
  • default
    접근 제어자를 생략했다면 default 접근 제어자를 가진다. 같은 패키지에서만 호출할 수 있다.
  • private
    오로지 클래스 내부에서만 사용할 수 있다.

변수의 경우 변수를 변경 못하게 하여 메서드를 통해 변경이나 조회할 수 있도록할때 접근 제어자를 많이 사용한다.

클래스패스 CLASSPATH

CLASSPATH란 JVM이나 Java 컴파일러에 사용자 정의 클래스와 패키지의 위치를 지정해주는 파라미터이다. 클래스를 찾기위한 경로라고 보면된다. JVM은 CLASSPATH의 경로를 확인하여 라이브러리 클래스들의 위치를 참조하게 된다. .class파일을 찾을 때 classpath에 지정된 경로를 사용하며 기본적으로는 java명령을 실행하는 위치를 의미한다. classpath는 .class 파일이 포함된 디렉토리와 파일을 ;으로 구분한 목록이다.

JVM의 클래스로더는 런타임 시에 $CLASSPATH 환경변수를 호출해 해당 디렉토리에 정의된 클래스들을 로딩하게 된다.
Class Loader는 3가지가 존재한다.

classloader
이미지 출처 : https://www.notion.so/ed8e346f88f54849a06ff968b1877ca5

  • BootStrap Class Loader
    기본 클래스 로더 중 최상위 클래스 로더
    jre/lib/rt.jar에 담긴 JDK 클래스 파일을 로딩해준다.
    BootStrap Class Loader가 자동으로 메모리에 적재하기 때문에 String 클래스나 Object 클래스를 사용할 수 있는것이다.
  • Extension Class Loader
    익스텐션 클래스로더는 jre/lib/ext폴더나 java.ext.dirs 환경 변수로 지정된 폴더에 있는 클래스 파일을 로딩한다.
  • System Class Loader
    System Class Loader가 우리가 만든 Class를 메모리에 올리는 역할을 하는데, 그 때 classpath 기준으로 클래스들을 로드해준다.

classpath를 지정하는 방법은 두 가지가 있다.

  • CLASSPATH 환경변수 사용
  • java runtime에 -classpath 옵션 사용

CLASSPATH 환경변수 사용

컴퓨터 시스템 변수 설정을 통해 지정할 수 있다. JVM이 시작될 때 JVM의 클래스 로더는 이 환경 변수를 호출한다. 환경 변수에 설정되어있는 디렉토리가 호출되면 그 디렉토리에 있는 클래스들을 먼저 JVM에 로드한다. 최근에는 운영체제 상의 환경변수로 클래스패스를 설정하는 것은 지양하고 IDE나 빌드도구를 통해 클래스패스를 설정한다.

-classpath 옵션 사용

컴파일러가 컴파일 하기 위해서 필요로 하는 참조할 클래스 파일들을 찾기 위해서 컴파일시 파일 경로를 지정해주는 옵션이다. 다른 클래스에 의존하는 클래스의 소스 파일을 컴파일 하기 위해서 다른 클래스가 위치하는 경로를 잡아주는 것이다. -classpath 대신 단축어인 -cp를 사용해도 된다. classpath 옵션은 java와 javac 명령어에 모두 사용할 수 있다.

// Windows - 세미콜론 사용
java -cp ".;lib" ClasspathTest

// Linux, OSX 유닉스 계열의 시스템 - 콜론 사용
java -cp ".:lib" ClasspathTest

// . : 현재 디렉토리에서 클래스를 찾는다는 의미
// ; : 경로와 경로를 구분해주는 구분자
// lib : 현재 디렉터리에 없다면 하위 디렉토리 중 lib에서 클래스를 찾는다는 의미
// 만약 .을 제외한다면 현재 디렉토리의 클래스를 찾지 못한다. 하지만 하위 lib 디렉토리에 있는 클래스는 찾을 수 있다.

rt.jar

JRE는 JDK 중에서 java 프로그램을 실행하는 프로그램만 포함된 환경이다. 따라서 JRE는 classes.zip 파일에서 클래스를 찾지 않는다. 대신 rt.jar파일을 사용한다.
rt.jar 파일에는 classes.zip과 동일한 클래스가 모두 포함되어 있고 아카이브 형식과 이름만 다른것을 사용한다. Java 1.2에서 classes.zip 파일은 없어졌다. 그래서 jdk와 jre 모두 rt.jar를 사용한다.

참고
https://kils-log-of-develop.tistory.com/430
https://www.notion.so/ed8e346f88f54849a06ff968b1877ca5
https://blog.baesangwoo.dev/posts/java-livestudy-7week/
https://gintrie.tistory.com/67

반응형

'Programming > JAVA' 카테고리의 다른 글

예외란?  (0) 2021.02.13
인터페이스란?  (0) 2021.02.06
상속이란?  (0) 2021.01.07
클래스란?  (0) 2021.01.04
JUnit이란?  (0) 2020.12.31