포스트

(Day6) - 자바의 클래스, 패키지, 주석

이 글은 제가 교육을 수강하며 기록하고 추가한 내용입니다. 강사님과 무관하게 잘못된 내용이 있을 수 있습니다.


클라우드 기반 웹 데브옵스 프로젝트 개발자 교육 과정 (5기)

  • 비트캠프 엄진영 강사님 (https://github.com/eomjinyoung/)
  • 훈련기관 : 네이버클라우드주식회사
  • 기간: 2023-11-14 ~ 2024-5-22
  • 남은 일자 : 123 일 ( 6/129 )

6일(2023-11-21,화)

강의 내용

복습

인터프리트 방식에 대하여

인터프리트 방식은 보통 컴파일 방식과 비교된다.

기계어가 아니면 CPU가 이해를 못하니 소스파일을 한번에 전부 어셈블리어로 바꾸고 그걸 기계어로 다 바꿔서 실행하는 게 컴파일 방식이다.

인터프리트 방식은 다르다. 소스파일을 일단 읽고 문법검사를 한 다음에 해석한다. 그리고 인터프리터가 해당 해석 결과를 통해 OS가 실행하도록 한다.

인터프리트 방식을 쓰는 언어는 대표적으로 자바스크립트와 파이썬이 있다. 자바스크립트를 node.js를 통해 인터프리트 방식으로 실행해보자.

  1. node.js 를 설치한다.
  2. $node 파일명.js 를 통해서 소스코드를 실행한다.

인터프리트 방식은 특징이 있다.

  • 소스파일을 바로 컴파일하는 게 아니라 직접 읽는다.
  • 실행할 때 소스코드가 필요하다. (컴파일 방식은 컴파일된 결과인 어셈블리어 (실행파일)만 있으면 됐다.)
  • 소스코드 자체가 자산인데 노출될 가능성이 높다.
  • 인터프리트 방식은 소스코드를 노출해야 배포가 된다. 그래서 복호화가 있다.
  • 실행되는 라인별로 문법을 매번 검사한다.
  • 실행하고 오류가 발생하기 전까지 오류를 알 수 없다.
  • 그래서 속도가 컴파일 방식에 비해서 느리다.
  • 인터프리터가 있어야 한다.

참고. 라이센스 요약

GPL 라이센스: 내꺼 기반으로 소스 추가해서 니꺼 만들었어? 그러면 전체 공개해야 돼. LGPL 라이센스: 내꺼 기반으로 소스 추가해서 니꺼 만들었어? 음.. 너가 추가한 부분 공개 안해도 돼. 아파치/MIT 라이센스: 맘대로 바꿔도 돼. 공개도 안해도 돼. 돈 받고 팔아도 돼.

같은 오픈소스 프로젝트여도 보는 것만 되는 것도 있고 바꿔도 되는 것도 있고 바꾼걸 보여줘야 하거나 안보여줘도 되는게 있고 상업적으로 이용 가능하거나 불가능한 것도 있으므로 다양하다.

프로젝트 디렉토리는 왜 쓰는가? 관리의 용이성을 위해서다 프로젝트 디렉토리를 관리하기 위한 관례가 있다. 유명한 리포들에서 어떻게 작명을 하고 폴더를 관리를 하는지 보자.

  • 소스코드와 바이너리 파일은 각각의 폴더를 만들어 분리한다.
  • 폴더에서 공백을 표현하는 경우는 언더바가 아닌 마이너스를 쓴다. (-를 쓴다.)
  • 설정 파일도 분리한다.
  1. 소스파일을 저장하는 폴더는 src 경로로 쓴다. source를 줄인 말이다.
  2. 실행파일(바이너리코드)를 저장하는 폴더는 bin 이라는 이름으로 경로를 만들어 쓴다. (Binary code의 약자)

소스폴더에서 컴파일하면 그 결과가 bin 폴더로 자동으로 가도록 하고 싶은 것이다. Hello.class 실행파일은 mystudy에서 java src/Hello.java 의 결과이다.

루트 디렉토리에서 컴파일 및 실행을 둘 다 하려면?

Java -d bin src/Hello.java 명령어로 디렉토리를 따로 지정해주면 그 지정된 디렉토리에 컴파일 결과인 바이트코드 파일을 생성한다.

바이트코드를 실행할 떄는 이렇게 하자. java -classpath bin Hello

경로 알려주고, class파일 이름 알려주는 것이다. 줄이면 java -cp bin Hello 라고 하면 된다.

프로젝트가 하나인 경우 루트 밑에 하나의 프로젝트 디렉토리만 쓰고, 프로젝트가 여럿인 경우 루트 밑에 다수의 프로젝트 디렉토리를 생성한다.

보통은 하나의 깃 저장소(리포)에 프로젝트를 하나만 둔다 그러나 때때로 하나의 프로젝트에 여러개의 서브프로젝트가 붙는 경우가 있다. 이 때 하나의 리포를 써서 형상관리를 하려고 한다면, 위 방법처럼 관리하면 된다. (실무에서는 대부분 리포 하나에 하나의 프로젝트만 관리한다.)

https://github.com/spring-projects/spring-framework 이런 경우가 여러 프로젝트를 하나의 리포로 관리하는 예시이다.

https://github.com/mybatis/mybatis-3 마이바티스3 리포같은 경우는 1리포 1프로젝트의 좋은 예시이다.

C는 50년이 넘었는데 아직도 쓰고 있다. 깃도 오래 쓸거고, 소스코드 관리도 유사하게 관리될 수 있다. ( … AGI가 나오면 인간의 관습을 따를까?)

자바 프로젝트들이 더 복잡해지면서 설정 파일도 따로 분리하게 되었다. 특히 Maven 빌드 도구에서 쓰는 것이 사실상의 표준(de facto)이 되어버렸다.

거의 모든 자바 개발자들이 메이븐 빌드 도구의 방식대로 설정파일을 따로 관리한다는 것이다. 그러면 그 관리 방법은 무엇일까?

1
2
3
4
5
6
7
8
9
10
11
12
13
project/

-   src/
	-   main/  : 어플리케이션 소스 파일을 두는 폴더
		-   java/  :자바 소스코드를 두는 폴더
		-   resources/  :설정파일을 두는 폴더
		-   kotlin/  :코틀린 소스코드를 두는 폴더
		-   …
	-   test/  : 단위 테스트 소스파일을 두는 폴더
		-   java/
		-   resources/
		-   …
# 단위 테스트는 납품 제조사의 시험성적서 같이 개별 기능을 테스트하는 것.

위 트리처럼 프로젝트 폴더를 관리하는 것이 지켜야 할 관례이다. 손으로 하나하나 경로를 생성하기는 너무 귀찮을 것이다. 이 또한 빌드 도구를 이용하여 관리할 수 있다. 그래서 그레이들은 배운 것이다. 그레이들을 통해서 직접 시험해보자. gradle init 참고로 그레이들은 자바로 만들어졌기에 맥 리눅스 유닉스 윈도우 다 돌아간다.

그레이들의 컴파일에 관하여

그레이들에는 자체적인 자바 컴파일러가 포함된 것이 아니다. 설치된 컴파일러를 그레이들이 사용하는 것이다.

개발자가 직접 컴파일러를 사용할 수 있는데 그러지 않고 그레이들을 통해서 하는 이유는 뭘까? 그레이들 빌드 스크립트 작성법을 알아야 그레이들이 컴파일러를 쓰게 할 수 있을텐데 말이다.

=> 이건 그레이들의 자바 플러그인이 어떻게 동작하는지 알아야 한다.

Java 문법

패키지 문법

유지보수를 쉽게 하기 위해서 프로그램을 분리하면? 그것이 클래스 파일이다. 클래스 파일을 디렉토리로 분류하면? 그것이 패키지 문법이다.

패키지와 디렉토리, 패키지와 클래스의 관계

패키지는 디렉토리로 구현된다. 그런데 디렉토리는 상하위 구분자로 / (슬래시)를 쓰는데 패키지는 . (닷)을 쓴다. (윈도우는 \ 백슬래시)

자바에서 패키지, 디렉토리, 클래스는 코드의 구조화와 조직화를 위해 사용되는 중요한 요소들입니다.

  1. 패키지(Package):
    • 패키지는 관련된 클래스와 인터페이스를 그룹화하기 위한 자바의 구조화 메커니즘입니다.
    • 패키지는 관련된 클래스들을 묶어서 네임스페이스를 제공하고, 클래스 이름의 충돌을 방지합니다.
    • 패키지는 소문자로 시작하며, 일반적으로 역순 도메인 이름을 사용하여 명명됩니다.
  2. 디렉토리(Directory):
    • 디렉토리는 파일 시스템에서 파일을 구조화하는 방법 중 하나입니다.
    • 자바에서 패키지의 물리적 표현은 디렉토리 구조로 이루어져 있습니다.
    • 예를 들어, 패키지 com.example.myproject는 디렉토리 구조에서 com 디렉토리 내에 example 디렉토리, 그 안에 myproject 디렉토리를 포함합니다.
  3. 패키지와 클래스의 관계:
    • 패키지는 클래스를 논리적으로 그룹화하고, 디렉토리는 파일 시스템에서 이를 물리적으로 표현합니다.
    • 패키지 내에서 클래스를 작성할 때, 해당 클래스는 그 패키지에 속하게 됩니다.
    • 예를 들어, com.example.myproject 패키지 내에서 MyClass라는 클래스를 작성하면 클래스의 전체 이름은 com.example.myproject.MyClass가 됩니다.
    • 또한, 이 클래스 파일은 파일 시스템에서 com/example/myproject 디렉토리에 저장됩니다.

간단한 예를 들어보면:

1
2
3
4
5
/src
  └── com
      └── example
          └── myproject
              └── MyClass.java

위 구조에서 MyClass.java 파일은 com.example.myproject 패키지에 속하는 클래스를 나타냅니다.

패키지 클래스의 컴파일과 실행

패키지 클래스를 컴파일하고 실행하는 프로세스는 일반적으로 다른 클래스와 크게 다르지 않습니다. 다만 패키지의 사용과 관련된 몇 가지 주의 사항이 있습니다.

1. 컴파일(Compile):

패키지 선언:

1
2
3
4
5
6
7
8
// MyClass.java
package com.example.myproject;

public class MyClass {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

컴파일 명령어:

1
javac com/example/myproject/MyClass.java

주의사항:

  • 소스 코드 상단에 패키지 선언이 있어야 합니다.
  • 디렉토리 구조와 일치하도록 패키지와 디렉토리를 구성해야 합니다.
  • 컴파일 시에는 클래스 파일이 패키지 구조에 맞게 생성됩니다.

2. 실행(Run):

실행 명령어:

1
java com.example.myproject.MyClass

주의사항:

  • java 명령어 뒤에는 클래스의 전체 이름(패키지 포함)을 제공해야 합니다.
  • 클래스 파일이 현재 디렉토리 또는 클래스패스에 올바르게 위치해야 합니다.
  • 클래스 내의 main 메서드가 있는지 확인해야 합니다.

패키지 클래스의 실행 예시:

  1. 디렉토리 구조:
    1
    2
    3
    4
    5
    
    /src
      └── com
          └── example
              └── myproject
                  └── MyClass.java
    
  2. 컴파일:
    1
    
    javac com/example/myproject/MyClass.java
    
  3. 실행:
    1
    
    java com.example.myproject.MyClass
    

이렇게 하면 MyClassmain 메서드가 실행되어 “Hello, World!”가 출력됩니다. 패키지의 사용은 주로 코드를 조직화하고 네임스페이스를 관리하는 데 도움이 됩니다.

패키지 이름과 도메인 명

도메인 명과 패키지 이름의 관계
패키지는 도메인을 거꾸로 한 것과 유사함! 세상에 얼마나 많은 패키지가 있겠는가? 그래서 충돌을 피하기 위해 도메인을 거꾸로 한 것을 패키지로 쓰자고 약속했다. (도메인은 겹치지 않으므로)
  • 예시:
    • 도메인 명: example.com
    • 패키지 이름: com.example.myproject

공개 클래스와 패키지 프라이빗 클래스, 소스파일명의 관계

소스파일과 클래스의 이름을 똑같이 하느냐? 에 따라 달라짐. 일단 똑같아야 공개 클래스가 될 수 있음.

1. 공개 클래스 (Public Class):

  • 소스 파일의 이름은 공개 클래스의 이름과 동일해야 하고 public 접근제어자 사용.
    1
    2
    3
    4
    
      // MyClass.java
      public class MyClass {
      // 클래스 내용
      }
    

2. 패키지 프라이빗 클래스 (Package-Private Class 또는 Default Class):

  • 소스 파일 이름 규칙:
    • 패키지 프라이빗 클래스의 경우 소스 파일의 이름과 클래스의 이름은 동일할 필요는 없음
    • 하나의 소스 파일에 여러 패키지 프라이빗 클래스를 정의할 수 있음.
    • 다른 클래스에서 사용 불가함.
    1
    2
    3
    4
    
    // MyClass.java 
    class PackagePrivateClass { // 소스파일과 클래스 이름 다름!
        // 클래스 내용
    }
    

3. 여러 클래스가 있는 소스 파일:

  • 소스 파일 이름 규칙:
    • 소스파일과 이름 같은 클래스만 공개 클래스로 할 수 있음 (이를 주요 클래스라고 함)
    • 나머지는 자동으로 패키지 프라이빗 클래스가 됨.
  • 예시:
    1
    2
    3
    4
    5
    6
    7
    8
    
    // MainClass.java
    public class MainClass {
        // 주요(public) 클래스 내용
    }
    
    class AnotherClass {
        // 다른 클래스 내용
    }
    

    권장사항

    굳이 여러 클래스를 하나의 소스파일 안에 만들지 말자. 어디에 무슨 클래스가 있는지 알기 어려워지기 때문이다.

패키지 소속 클래스를 사용하는 방법

두 가지가 있다.

  1. import
  2. 경로 명시

  3. 소스파일 최상단에서 import로 어떤 패키지를 쓸 것인지 알려준다.
1
2
3
4
5
6
7
8
9
// 패키지를 import하여 사용하는 예
import com.example.otherpackage.OtherClass;

public class MyClass {
    public static void main(String[] args) {
        OtherClass obj = new OtherClass();
        // OtherClass의 인스턴스를 생성하고 사용
    }
}
  1. 패키지를 import하지 않고 클래스의 풀 패키지 경로를 전부 명시

    1
    2
    3
    4
    5
    6
    7
    
     // 클래스의 풀 패키지 경로를 사용하는 예
     public class MyClass {
         public static void main(String[] args) {
             com.example.otherpackage.OtherClass obj = new com.example.otherpackage.OtherClass();
             // OtherClass의 인스턴스를 생성하고 사용
         }
     }
    

당연히 import 하는 게 가독성이 좋으므로 권장된다. 그런데 경로명시만 쓸 수 있는 경우가 있다. 그건 언제? => 클래스 이름이 충돌나는 경우다.

javadoc

Javadoc이란? 개발자가 작성한 코드의 사용법을 설명한 문서이다. 이는 클래스, 변수, 메서드 상단에 작성된 주석을 통해서 자동으로 작성되는 문서이다.

자동으로 생성된 문서는 HTML 형식이다. java 패키지가 배포되는 경우 다른 개발자들이 참조할 문서를 자동으로 만들어주니까 주석만 규칙에 맞게 잘 작성하면 문서관리의 부담이 확 줄어든다.

javadoc이 없었다면 소스파일과 API문서(doc, ppt, hwp, pdf 등)를 각각 작성해야 하는 아주 고통스러운(?) 형상관리를 해야 한다.

소스코드를 바꾸면 API 문서도 그에 맞춰 변경해야 하는데 개발자들이 API 문서는 최신화하지 않는 경우가 많았다. (안하는게 현실) 그래서 플젝이 끝나면 코드와 문서가 일치하지 않는 문제가 있었다.

이걸 해결하고자 고안된 방법이 소스에다가 문서를 결합하는 것이다. 그리고 문서 생성을 자동화시키는 것이다. 그리고 이런 문서 생성 자동화 솔루션의 대표가 javadoc이고, 다른 문서도 문서 생성 솔루션이 있다.

(사람이 힘들면 그 일을 안하는 건 법칙이다 ㅋㅋ)

자바 프로젝트를 Eclipse IDE로 가져오기

gradle init 을 통해 자바 프로젝트를 생성한 경우, eclipse 플러그인을 사용하도록 빌드 스크립트 파일을 설정해주자. 이후 gradle eclipse 명령어로 이클립스에서 프로젝트를 import 할 수 있게 해주고 가져오자.

패키지 멤버 클래스를 만들고 컴파일, 실행할 수 있는가? []

패키지 프라이빗 클래스와 공개 클래스를 설명할 수 있는가? []

패키지 멤버 클래스를 사용하는 방법을 아는가?

  • import 하는 방법
  • 풀 패키지 경로를 명시하여 사용하는 방법

자바 코드에 주석을 지정하는 세가지 방법과 용도를 설명할 수 있는가?



  1. 한 줄 주석 // 내용
  2. 여러줄 주석 /* 내용 */
  3. 어노테이션 주석 @내용 (다른 주석과 다르게 컴파일러가 무시하지 않는다!!)
  4. 문서화 주석 /** 내용 /
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.