본문 바로가기

JAVA/온라인 스터디

7주차 과제: 패키지

온라인 스터디 깃허브 주소: github.com/whiteship/live-study/issues/7

 

7주차 과제: 패키지 · Issue #7 · whiteship/live-study

목표 자바의 패키지에 대해 학습하세요. 학습할 것 (필수) package 키워드 import 키워드 클래스패스 CLASSPATH 환경변수 -classpath 옵션 접근지시자 마감일시 2021년 1월 2일 토요일 오후 1시까지.

github.com

목표

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

학습할 것 (필수)

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

마감일시

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

 

*해당 포스트는 "이것이 자바다"라는 책을 기반으로 서술 되었습니다. 오탈자 및 잘못 쓰인 내용은 알려주시면, 정정하겠습니다. 고맙습니다.


1. Package 키워드

패키지는 클래스를 체계적으로 관리하는 방법이다. 패키지를 이용하여, 프로그램을 만들 때 생성되는 여러 클래스들의 구조를 나눌 수 있고, 편리하게 찾아갈 수 있다. 즉 패키지란 쉽게 우리가 컴퓨터에서 여러 파일들의 폴더 역할을 생각하면 쉽다. 

 

그렇다고, 패키지랑 클래스를 별개로 생각해서는 안 된다. 만약 클래스가 패키지 안에 속해있다면, 클래스를 찾아가기 위한 주소는 패키지부터 시작해야 한다.

 

클래스 전체 이름: 패키지명+클래스명

 

그 이유는, 클래스 이름이 같더라도 패키지의 이름이 다르다면, 생성이 되기 때문이다. 즉 서로 다른 패키지라면 같은 클래스 이름도 존재할 수 있다. 이런만큼, 패키지는 클래스를 구분해주는 역할도 한다. 

 

그렇다면 패키지명과 함께 클래스의 이름을 적어주기 위해서는 어떻게 표현을 해야 할까?

상위패키지.하위패키지.클래스

위의 예시처럼 (.) 도트 연산자를 활용하여, 구분을 해주면 된다.

 

만약, com이라는 상위 패키지에 apple이라는 패키지가 속해 있다면, com.apple이 패키지의 명칭이 된다. 

그리고 그 apple 패키지에 projectName.class 파일이 존재한다면 해당 클래스의 전체 이름은 com.apple.projectName이 될것이다. 해당 설명을 그림으로 표현하면, 다음과 같다. 

 

이렇게 상위 패키지 밑에 하위 패키지가 생성이되고, 그 하위 패키지에 클래스가 생성이 되는 구조인것일 알 수 있다. 

만약, 해당 projectName 클래스가 com.apple이라는 패키지에 생성이되었는데, 갑자기 다른 패키지 com.samsung 패키지에 저장을 한다면 projectName.class 파일은 사용을 할 수 없다. 즉, 클래스를 이동하고자 한다면, 패키지 전체를 이동해야 한다. (패키지 이름도 함께 바꿔야 한다.)

 

1.1 패키지 선언

패키지는 클래스를 컴파일하는 과정에서 자동으로 생성이된다. 컴파일러는 클래스에 포함되어 있는 패키지 선언을 보고, 파일 시스템의 폴더로 자동 생성을 한다. 그렇다면, 패키지 선언은 어떤 방식으로 하게 될까?

 

package 상위 패키지, 하위 패키지;

public class ClassName {...}

이런식으로, 클래스가 시작하기 전 가장 상단에 생성을 하면 된다. 패키지의 이름도 개발자가 임의로 지을 수 있지만, 약간의 규칙이 필요하다. 다음은 패키지 선언을 하기 위한 규칙이다.

 

1. 숫자로 시작해서는 안 된다.

2. _, $를 제외한 특수문자도 사용해서는 안 된다.

3. java로 시작하는 패키지는 자바 표준 API에서만 사용하므로, 사용해서는 안 된다.

4. 모두 소문자로 작성하는 것이 관례이다. 

 

클래스와는 다르게 패키지는 보통 모두 소문자로 작성을 하게 된다.

 

보통 여러 개발 회사가 함께 참여하는 대규모 프로젝트에서는 회사를 구분짓는 패키지명을 사용하기 위해, 겹칠 수 없는 는 도메인 명을 자주 활용한다. 도메인 이름은 역순으로 패키지 이름을 지어주게 되며, 그 이유는 보다 더 포괄적으로 사용할 수 있는 이름이 상위에 위치하게끔 이다. 다음은 해당 예시이다. 

 

com.apple.projectName
com.lg.projectName
com.google.projectName

 

1.2 패키지 선언이 포함된 클래스 파일

패키지 선언이 포함된 클래스 파일을 컴파일 할 경우, javac 를 이용하여 생성을 할 수 없다. 즉, 단순하게 javac ClassName.java를 한다고 생성이 되지 않는다. 

패키지 폴더가 자동 생성되기 위해서는 -d 라는 옵션과 함께 패키지 명을 함께 적어주어야 한다. 

javac     -d    .     ClassName.java          // 현재 폴더 내에 생성
javac    -d    ..\bin    ClassName.java        // 현재폴더와 같은 위치에 있는 bin 폴더에 생성
javac   -d   C:\Temp\bin  ClassName.java         //C:\Temp\bin 폴더에 생성

또한, 명령프롬포트 창에서 컴파일을 완료하고, 실행을 하기 위해서는 패키지가 시작되는 폴더에서 java 명령어를 사용해야 한다. 즉, 바이트 코드 파일 class 파일의 디렉토리가 아닌, 패키지의 시작 점에서 java 명렁어를 사용 하면 된다. 


2. Import 키워드

import 키워드는 주로 클래스에서 다른 패키지에 소속되어 있는 클래스에 있는 메소드를 사용하고자 할 때 쓰인다. 이 말을 다시 설명하자면, 클래스는 같은 패키지 내에 있다면, 아무런 키워드 없이 자유롭게 사용이 가능하다. 하지만, 다른 패키지에 존재하는 클래스를 사용하기 위해서는 두 가지의 선택지가 존재한다. 

 

1. 패키지와 클래스를 모두 기술하기
2. import 문 사용하기

2.1 패키지와 클래스를 모두 기술하기

다른 패키지의 클래스를 사용하기 위해서 사용할 수 있는 첫번쨰 방법이다. 다른 패키지의 클래스 이름을 전체 써주면 된다.예를 들어, com.lg 패키지에 소속된 Phone 클래스를 사용하고자 할때, 다음과 같이 코드를 작성하면 된다.

 

package com.apple;

public class Mobile{

    com.lg.Phone iphone = new com.lg.Phone();
}

새로운 객체를 생성하기 위해서, Phone이라는 클래스를 사용했는데, 이때 Phone클래스는 com.lg 패키지에 위치해 있어, 해당하는 클래스의 전체 이름을 기술해준 것을 볼 수 있다. 

하지만, 코드를 작성할 때, 매번 이렇게 전체 이름을 기술하는 것은 굉장히 번거로운 과정이다. 그래서 이러한 과정을 줄여주는 키워드가 존재한다. 그게 바로 import이다.

 

2.2 import문 사용하기

import문을 사용하기 위해서는, 사용하고자 하는 패키지 이름만 써주면 된다. 이렇게 한 번 import만 해주면, 해당 패키지의 클래스를 패키지명 없이 자유롭게 사용이 가능하다. import 문은 패키지 선언과 클래스 선언 사이에 위치하면 된다. 

 

package com.apple;

import com.lg;

public class Mobile{

    Phone iphone = new Phone();

}

만약, 한 패키지에 여러개의 클래스가 존재할 경우에는 한 개의 클래스를 지정해서 import 하는 방법도 있겠지만, 그냥 패키지명 뒤에 *를 사용한다면, 해당하는 패키지의 모든 클래스들을 import할 수 있다. 

 

만약, 두 개의 패키지를 import했는데, 두 패키지에 동일한 이름을 가진 클래스가 존재할 경우에는 import를 했더라도, 패키지명부터 클래스명까지 전체를 기술해주어야 한다는 사실을 기억하자. 


3. 클래스패스 (CLASS PATH)

클래스 패스란, 클래스의 경로를 지정하여, 자바가 필요로 하는 클래스를 로드하는 것을 지정한다. 

즉 JVM이 우리가 작성한 소스코드를 읽을 떄, 여러 클래스들을 import했다고 생각해보자, import한 것은 알겠는데, 그렇다면 import했던 그 패키지는 어디에 있는지 일일히 찾아야 한다. 

 

그때 우리는 이 경로에 클래스가 있다고 알려주는게 바로 클래스패스이다. 보통은 매번 이렇게 클래스 패스를 알려주는 것이 귀찮아 환경변수를 지정하기도 한다. 하지만 이는 운영체제 별로 설정을 해야 하는 단점이 존재한다는 것을 기억해두자. 


4. CLASSPATH 환경 변수

환경변수란 운영체제에 지정하는 변수로 자바 가상머신과 같은 어플리케이션들은 환경변수의 값을 참고해서 동작을 한다. 자바는 클래스 패스로 환경변수 CLASSPATH를 사용하는데 이 값을 지정하면, 실행을 할 때마다 -classpath옵션을 사용하지 않아도 되므로 편리하다. 하지만, 운영체제를 변경하면 클래스 패스가 사라지므로 이식성 면에서 불리하다. 

 

다음은 Windows에서 환경 변수를 설정하는 방법이다. 

forbeginnerdevs.tistory.com/1?category=892345

 

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

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

forbeginnerdevs.tistory.com

 


5. -classpath 옵션

출처: https://www.mankier.com/1/javac-java-11

위의 표는 classpath를 사용할 떄, 자주 사용하는 옵션들을 정리한 표이다. 이 외에도 다양한 옵션들이 사용될 수 있으며, 해당 출처를 참고하면 편리하다. 


6. 접근 지시자

main()메소드가 없는 클래스들은 다른 클래스에서 해당 클래스를 사용하고자 만들어졌다. 즉 라이브러리로서, 외부 클래스에서 접근을 할 수 있는 멤버와 접근을 할 수 없는 멤버를 구분해서 필드, 생성자, 메서드를 설계해야 한다. 자바에서는 이러한 기능을 위해, 접근 지시자, 접근제한자 (Access Modifier)를 제공한다. 

 

접근 제한자는 총 4가지로 구성이 되었으며, public, protected, default, private이 존재한다. 해당 접근 제한자들을 간단하게 설명하자면 다음과 같다. 

public은 외부 클래스에서 자유롭게 사용이 가능한 공개 멤버를 만든다.

protected는 같은 패키지 내에서만 자유롭게 사용이 가능한 공개 멤버이다. 단, 만약 상속 관계에도 자유롭게 접근이 가능하다. 

private는 같은 클래스내에서만 사용이 가능하며, 외부 클래스에서는 접근이 불가하다. 

저 3가지의 접근 제한자를 사용하지 않을 경우를 default 접근 제어자가 자동으로 붙게 된다. 이 경우에는 같은 패키지 내에서만 자유롭게 호출이 가능하다. 

 

각 접근제어자 별로 외부 클래스로부터의 접근 제한의 강도를 표현했다. 아래로 갈 수록, 외부 클래스에서 접근을 할 수 있는 범위가 좁아진다는 것을 표현했다. 

출처: 이것이 자바다

이 접근 제어자는 사용할 수 있는 영역과 어느 클래스에 이를 활용할 수 있는지가 정해져있다. 다음은 이와 관련된 내용을 정리한 표이다. 

출처: 이것이 자바다

그렇다면, 구체적으로 클래스, 메서드, 생성자와 필드에서 각각 어떻게 접근제한이 쓰일 수 있으며, 어느 범위까지 접근이 제한이 가능한지 살펴보겠다. 

6.1 클래스의 접근 제한

클래스를 생성할 때는 외부에서 접근을 허용할 것인지 아닌지에 따라서 접근제한자를 선택하면 된다. 만약 아무 접근제한 없이 선언을 하게 되면, default 가 자동으로 컴파일러가 붙여준다.(소스코드엔 당연히 보이지 않는다.)

 

그에 반해, public 을 사용하게 된다면, 어떤 외부 클래스에서도 접근을 할 수 있게 된다. 즉, 다른 개발자들이 해당 클래스를 접근할 수 있게 하려면 public을 사용해야한다는 사실을 기억해야 한다. 

 

6.2 생성자의 접근 제한

생성자의 접근 제한도 클래스의 접근 제한과 동일하게 연장선으로 생각하면 이해가 쉽다. 아무 접근 제한자가 없으면, default가 된다. 다음은 생성자에게 어떤 접근 제한자를 썼는지에 따라 어떻게 쓰이는지에 대한 표로 정리한 설명이다. 

 

6.3 필드와 메소드의 접근 제한

필드와 메소드의 접근제한도 동일한 연장선이라 생각하면 쉽다. 대신, 이 필드와 메소드의 사용처를 클래스 내부에서만 쓸것인지 외부에서도 사용가능하게 할 것인지에 따라서 접근 제어자가 붙는 다고 생각하면 편하다. 다음은 필드와 메소드에 관한 접근제어자들을 정리했다. 

 

 

참고자료

1. 이것이 자바다.

2. 생활 코딩 클래스패스 : opentutorials.org/module/516/5527

www.mankier.com/1/javac-java-11

 

javac-java-11 command man page - java-11-openjdk-devel

Generates class files that target a specified release of the virtual machine. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), 1.7

www.mankier.com

3. www.geeksforgeeks.org/classpath-in-java/

 

'JAVA > 온라인 스터디' 카테고리의 다른 글

6주차 과제: 상속 #6  (0) 2020.12.21
[5주차] 클래스  (0) 2020.12.14
[4주차] 제어문 #4  (0) 2020.12.10
[3주차] 연산자  (0) 2020.11.27
2주차 라이브 방송 정리  (0) 2020.11.22