본문 바로가기
스터디/[white-ship] 자바 스터디(study hale)

7주차 과제: 패키지

by doyoungKim 2021. 1. 1.

목표

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

학습할 것 (필수)

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

마감일시

2021년 1월 2일 토요일 오후 1시까지.


Package 목적

어떤 상품들을 묶어서 용도나 목족에 맞춰서 분리 한 것을 의미한다. e.g 제주도 여행 패키지, 베트남 여행 패키지

제주도와 베트남 여행 패키지 안에는 비행기표 라는 같은 이름을 가진 내용물이 있다.

이 비행기표는 하나는 제주도 하나는 베트남 을 가는 다른 비행기표이다.

비행기표라는 이름 만 들었을 때는 목적지를 쉽게 알수 없기 때문에, 제주도 여행 패키지 안에 있는 비행기표 이렇게 표현할 수 있는 것이다.

 

Package 의미

예를 들어, ArrayList 라는 클래스를 본다면, 이 클래스는 

Java.util 이라는 패키지에 있다. 처음 Java 로 시작 했으니 자바에서 제공하는 클래스임을 짐작할 수 있고 util 을 통해 유용한 도구들이 있는 패키지 구나 라고 이해할 수 있다.

또한, 프로그램을 작성하다 보면 다른 기업에서 만든 클래스를 직간접적으로 사용할 때 가 많은데, 기업의 고유정보등을 이용하여 패키지를 작성하면 클래스의 이름이 충돌하는 것을 방지할 수 있다.

 

Package 작성 관례

  • 클래스의 이름과 구분이 되도록 패키지의 이름은 모두 소문자로 구성한다.
  • 인터넷 도메인 이름의 역순으로 패키지 이름을 구성한다.
  • 패키지 이름의 끝에 클래스를 정의한 주체 또는 팀을 구분하는 이름을 추가한다.

예를 들어, 인터넷 주소가 doyoung.tistory.com 인 회사의 blog 팀에서 개발한 클래스를 묶을 패키지 이름을 위의 관례에 따라서 만들면 다음과 같다.

com.tistory.doyoung.blog

 

Package 선언

Test 라는 클래스를 IDEA 를 통해 만들게 되면 자동적으로 package 선언이 된다.

package com.company.packages; // 패키지 선언

public class Test {
}

패키지를 선언하는 이유는 컴파일 했을 때 생기는 class 파일을 어디다가 배치 할 것인가 를 정하기 때문이다.

다음과 같은 명령어를 실행 했을 때 패키지와 같은 경로에 컴파일 된다.

 javac src/main/java/com/company/packages/Test.java 

 

 

import

같은 패키지 안에서 만들어진 클래스들을 대상으로 하는 인서턴스를 생성하는 상황이라면 클래스이름만으로 사용할 수 있다.

또한 java.lang 패키지 에 있는 클래스들또한 이름만으로 사용할 수 있다.
(String, Runnable, System.out.println ... )

JVM 내부에는 부트스트랩 클래스로더라고 최상단에 존재하는 녀석이 있다.

 

1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.

목표 자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기. 학습할 것 JVM이란 무엇인가 컴파일 하는 방법 실행하는 방법 바이트코드란 무엇인가 JIT 컴파일러란 무엇이며 어떻게 동작하는지 JV

doyoung.tistory.com



이 부트스트랩 클래스로더의 매커니즘은 내가 읽으려는 클래스가 부모한테 있는지 물어보고 있으면 쓰고 없으면 자기가 읽는다.
java.lang 은 최상단에 있는 부트스트랩 클래스로더가 이미 읽어 놨기 때문에 그냥 쓸 수 있다.

java.lang 패키지 에 있는 클래스 예시

 

하지만 위와 같은 조건에 만족하지 않는다면, 즉 java.lang 패키지와 같은 패키지가 아닌 클래스를 대상으로 인스턴스화 해야한다면, 다음과 같은 오류를 확인할 수 있다.

cannot resolve symbol '...'

 

 

따라서 패키지 정보를 입력해줘야한다.

1. import 로 명시

package com.company.packages.p1;

import com.company.packages.Person;

public class Doyoung extends Person {

    public Doyoung() {
        super("doyoung");
    }
}

 

package 와 클래스 명시 사이에 작성되며 위 import 문의 뜻은

"지금부터 Person 이라고 하면 com.company.packages.Person 을 의미하는 것으로 간주해라" 라는 뜻이다.

따라서 인스턴스를 Person 으로 짧게 쓸 수 있다.

 

2. 직관적으로 명시

클래스 이름 앞에 직관적으로 명시하는 방법이다. 

패키지 정보와 클래스 이름을 합쳐서 표현하면된다. FQCN(Fully Qualified Class Name)

public class Doyoung extends com.company.packages.Person {

    public Doyoung() {
        super("doyoung");
    }
}

 

 

단점으로는 코드가 늘어지고 읽는데 불편하기 때문에 꼭 써야하는 상황이 아니라면 잘 쓰지 않는다.

꼭 써야 할 때는 다음과 같다. 

각각 패키지가 다른 person 이라는 이름을 가진 두 개의 클래스가 있다.

 

package com.company.control;

public class Person {

    private String name;
    private int age;
    private String gender;

    private String nationality;

    public Person(String name, int age, String gender, String nationality) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.nationality = nationality;
    }
}

 

package com.company.packages.p1;

public class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

 

각각 다른 Person 을 한 공간에서 사용하려면 패키지로 구분 할 수 밖에 없다. 

package com.company.packages;

public class PersonUsing {
    public static void main(String[] args) {
        com.company.control.Person person1 = new com.company.control.Person("name", 12, "man", "korea");
        com.company.packages.p1.Person person2 = new com.company.packages.p1.Person("person");

    }
}

 

 

 

접근 제어자 (클래스, 메소드 인스턴스 및 클래스 변수)

다른 패키지에 있는 클래스를 접근 제어자를 통해서 제어 할 수 있다. 물론 클래스 뿐만 아니라 메소드, 인스턴스 및 클래스 변수 도 포함된다.

접근 제어자는 선언될 때 왼쪽에 명시 할 수 있고 종류는 다음과 같다.

  • pubilc : 누구나 접근가능
public class Doyoung { // public

	...
   
}

 

  • Protected : 같은 패키지 내에 있거나 상속받은 경우에만 접근 가능
public class Person {

    protected String setName(String name) { // protected
		this.name;
    }
}

 

  • (package-private) :  (아무 접근제어자가 없을 경우) 같은 패키지 내에 있을 때만 접근 가능
public class Person {

    String name; // package-private
    
}

 

  • private
public class Person {
    
    private String name; // private

	...
}

 

 

출차: https://t1.daumcdn.net/cfile/tistory/22703F5057E60F262E

 

 

CLASSPATH 환경변수

CLASSPATH

'패스(Path)' 라는 단어는 경로를 의미한다. 그리고 자바에서 '클래스 패스' 가 의미하는 바는 다음과 같다.

"자바 JVM이 클래스 파일(*.class)을 찾는 경로"

즉, 자바 가상머신은 프로그램의 실행 과정에서 클래스 파일을 찾을 때, 이 '클래스 패스' 라는 것을 기준으로 찾는다.

import구문이 예를 들어 다음과 같이 있다고 생각해보자.

import com.company.packages.Person;

 

Person 이라는 클래스는 정말 com.company.packages.Person 일까?

아니다.

실제 경로는 다음과 같다.

 

/Users/doyoung/work-space/live-study/src/main/java/com/company/packages

 

그렇다면 import 문을 수행하려면, 위와 같은 경로를 알아야하는데,

CLASSPATH 를 잡아주면, 위 경로를 루트 디렉토리로 부터나 현재 디렉토리로부터 Person 을 찾는 것이 아니라 

/Users/doyoung/work-space/live-study/src/main/java/

 

로 부터 찾을 수 있도록 하여 import 문을 수행할 수 있도록 해준다.

 

환경변수

운영체제 상에서 동작하는 응용프로그램들이 참조하기 위한 설정이다. 광범위한 변수다.

개발환경을 설정할 때 셋팅하는 환경변수가 대표적으로 CLASSPATH 환경 변수이다.

 

CLASSPATH 를 환경변수로 만드는 이유

자바 어플리케이션이 실행 될 때, 클래스 로더가 참조하여 라이브러리 클래스들을 로드해야 하는 데 이 용도로 사용된다.

예를 들어서, maven 프로젝트 안에서 다음과 같이 디펜던시를 설정 할 수 있는데,

 

이 디펜던시들을 다운받아서 클래스 패스를 다음 과 같이 만들어 사용할 수 있는 것이다.

*실제 저장되는 위치는 .m2 폴더 안이다.

 

-CLASSPATH 옵션

줄여서 -cp 옵션으로 쓰이기도 하다.

java 명령어 또는 javac 명령어 실행시 클래스패스를 지정할 수 있는 옵션이다.

A 위치에 있는 클래스를 컴파일을 하기위해서 필요한 클래스들이 B 에 존재하다면 다음과 같이 명령어를 사용할 수 있다.

javac -classpath B A

 

만약 필요한 클래스들이 다른 위치에 더 있다면 (A 위치 포함) 이렇게 작성할 수 있다.

javac -classpath .;B;A;C A

 

 

 

출처

728x90

'스터디 > [white-ship] 자바 스터디(study hale)' 카테고리의 다른 글

5주차 과제: 클래스  (0) 2021.01.01
5주차 과제: BinaryTree 이론  (0) 2021.01.01
5주차 과제: BinaryTree 실습  (0) 2021.01.01
0주차 : kick off  (0) 2020.12.26
6주차 과제: 상속  (0) 2020.12.26

댓글