[혼공자] 01-3. 자바 프로그램 개발 과정

Benjamin·2023년 2월 3일
0

혼공자

목록 보기
1/27

01-3. 자바 프로그램 개발 과정

자바 프로그램을 개발하기 위해
1. 파일 확장명이 .java인 텍스트파일을 생성하고, 자바 언어로 코드를 작성해야한다.
2. 이렇게 만들어진 자바 소스파일을 컴파일러인 javac명령어로 컴파일한다.
3. 컴파일이 성공하면 확장명이 .class인 바이트 코드 파일이 생성된다.

  • 바이트 코드 파일
    완전한 기계어가 아니므로 바로 실행할 수 있는 파일이 아니다.
    완전한 기계어로 번역해서 실행하려면 java명령어를 사용해야한다.

자바 소스 파일 (.java) -> javac 명령어로 컴파일 -> 바이트 코드 파일 (.class) -> java명령어 -> 기계어(JVM이 기계어 번역 후 실행함) -> 실행

바이트 코드 파일과 자바 가상 기계

자바 프로그램은 완전한 기계어가 아닌, 바이트 코드 파일(.class)로 구성된다.

  • 바이트 코드 파일
    운영체제에서 바로 실행할 수 없고, 자바 가상 기계(JVM)라는 번역기가 필요하다.
  • 자바 가상 기계 (JVM)
    Java Virtual Machine
    JDK에 포함되어있는 소프트웨어.
    바이트 코드 파일을 운영체제를 위한 완전한 기계어로 번역하고 실행하는 역할
    java명령어에 의해 구동됨

자바가 JVM을 사용하는 이유 = 바이트 코드 파일을 다양한 운영체제에서 수정하지 않고 사용할 수 있도록 하기 위함이다.


javac 명령어로 컴파일된 바이트 코드 파일은 JDK가 설치된 어떠한 운영체제에서도 java명령어로 동일하게 실행할 수 있다.
각 운영체제의 JVM은 바이트 코드 파일을 해당 운영체제에서 실행 가능한 기계어로 번역해서 실행하기 때문이다.
따라서 개발자는 운영체제 상관없이 자바 프로그램을 개발할 수 있다.

프로젝트 생성부터 실행까지

프로젝트를 생성하면, New module-info.java 대화상자가 나타난다.
이클립스가 생성하는 프로젝트는 모듈로 만들어지기 때문에, 모듈 기술자(Module Descriptor)라고 부르는 module-info.java가 필요하다.
-> JDK 8이하 버전은 module-info.java를 생성하면 오히려 컴파일 오류가 발생한다.

모듈명을 꼭 프로젝트명과 동일하게 할 필요는 없다.
하지만 명령라인에서 프로젝트를 실행할 때 모듈명이 필요하다. 이때 모듈명을 모른다면 module-info.java 내용을 보고 확인하면 된다.

module chap01 { // chap01이 모듈명
	requires java.se; //Java SE(JDK)가 제공하는 모든 모듈이 필요하다는 뜻
}

학습하며 별다른 설명이 없는 한 모든 프로젝트의 module-info.java파일에는 위와같은 내용을 작성하는것이 좋다.

  • 패키지
    자바는 소스 파일 및 컴파일된 바이트 코드 파일들을 기능별로 쉽게 관리하기 위해 패키지를 사용한다.
    패키지는 마치 파일 시스템의 폴더(디렉토리)와 비슷하다.
    -> 직접 생성하는 프로젝트도 모듈로 활용할 수 있기 때문에 반드시 패키지를 요구한다.

이클립스는 코드 작성을 완료한 후, 소스파일을 저장하면 자동으로 컴파일된다.

  • 자동 컴파일된 바이트 코드 파일의 위치!
    workspace경로\프로젝트명\bin폴더 내부에 패키지폴더아래 .class로 생성된다.

Run을 누르면, 생성된 바이트코드가 실행된다.

명령 라인에서 컴파일하고 실행하기

하지만 이클립스 개발 환경이 아니라 명령 프롬프트 또는 터미널과 같은 명령 라인에서 javac와 java 명령어로 소스 파일을 직접 컴파일하고 실행해야 하는 경우도 있다.

그래서 이 방법을 알아보겠다!

Mac의 경우사용자/[이름]/[eclipse-workspace]/[패키지명]/... 혹은 Windows의 경우 workspace경로\프로젝트명\-> 이 폴더를 열면 src폴더와 bin폴더를 확인할 수 있다.
src폴더에는 소스파일(~.java)이 저장돼있고, bin폴더에는 바이트 코드 파일(~.class)이 저장돼있다.
JDK11 이후 버전을 사용한다면, src폴더에 module-info.java가 있고, bin폴더에는 module-info.class가 있다.

1. 우선 이클립스를 종료하고, bin폴더 안에 있는 내용을 모두 삭제한다.

.classpath, .project는 이클립스에서 생성한 프로젝트를 위한 파일이니 신경쓰지 않아도 된다.

2. 명령 라인에서 bin, src바로 상단 폴더로 이동한다.

workspace경로\프로젝트명

3. src폴더에 있는 소스 파일을 javac명령어로 컴파일해서 바이트 코드 파일을 bin 폴더에 생성한다.

(JDK11이후 버전 명령어만 다루겠다.)
javac -d [바이트 코드 파일 저장 위치] [소스경로/module-info.java 소스 경로/*.java]
예시 )javac -d bin src/module-info.java src/sec03/exam01/*.java

*.java : 확장명이 java인 모든 파일을 말한다.

JDK11이후 버전부터는 모듈 기술자(module-info.java)도 컴파일 대상에 반드시 포함시켜야 한다.
그 이유는 모듈 기술자에 requires 키워드로 의존성 모듈이 기술되어 있기 때문이다.
컴파일러는 소스파일(~~/*.java)을 컴파일하기 위해 모듈 기술자에 기술된 의존성 모듈을 참고한다.

의존성 모듈
JDK8 이전 버전까지는 표준 API 전체가 제공되었기 때문에 문제가 없엇지만, JDK11 이후 부터는 JDK가 제공하는 표준 API를 모듈별로 쪼개어서 제공한다.
기본적으로 java.base 모듈을 사용할 수 있지만, 다른 모듈에 있는 API를 사용하고 싶다면 반드시 모듈 기술자에 의존성 모듈로 등록해야한다.
앞에서 작성했듯이 requires java.se를 쓴다면, Java SE(SDK)가 제공하는 모든 표준 모듈이 필요하다고 했기 때문에 Java SE전체에 의존성을 가진다. 이렇게 되면 JDK 8 처럼 표준 API전체를 제공받는 것과 동일한 효과가 난다.

javac 명령어로 컴파일 한 후 tree /f /a명령어를 실행하면, bin 폴더에 module-info.class와 바이트 코드 파일(~.class)이 생성된 것을 확인할 수 있다.

4. java명령어로 바이트 코드 파일을 실행할 차례이다.

(JDK11이후 버전 명령어만 다루겠다.)
JDK11 이후 버전부터 실행 방식이 달라진 이유는 역시 모듈 기술자(module-info.class)를 읽기위해서이다.

java명령어로 실행할 때는 .class를 생략한다.

java -p [바이트 코드 파일 저장 위치] -m 모듈/패키지이름.클래스이름
예시 ) java -p bin -m chap01/sec03.exam01.Hello

-m 옵션 뒤의 chap01이 모듈명인데, 모듈 기술자의 모듈명과 동일할 경우 JVM은 모듈 기술자의 내용을 읽고 바이트 코드 파일(/sec03.exam01.Hello)을 실행할 때 의존성 모듈을 참고한다.

프로그램 소스 분석

~.java가 생성된 패키지를 소스파일 최상단에 꼭 명시해야한다.
ex) sec03.exam01/Hello.java 일 경우, 코드 상단에 package sec03.exam01이라고 선언해야한다.

클래스 선언

public class Hello {
}

중괄호 {} 블록 앞부분 public class Hello클래스 선언부라고 한다.'
public class는 공개클래스라는 뜻이며, Hello는 클래스명이다.
클래스명은 소스파일명과 동일해야하며, 대소문자까지 일치해야한다.

  • 클래스 = 필드 또는 메소드를 포함하는 블록
  • 메소드 = 어떤 일을 처리하는 실행문들을 모아 놓은 블록

중괄호{}부분은 클래스 블록이라고 한다.

이렇게 작성하는것을 클래스 선언이라고 한다.

javac 명령어로 컴파일하면 Hello.class 바이트 코드파일이 생성되는데, 이 파일은 보통 Hello 클래스라고 간단히 부른다.

java명령어로 바이트 코드 파일을 실행하려면 클래스 블록 내부에 main() 메소드 블록을 갖고있어야한다.

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

중괄호{}블록의 앞부분인 public static void main(String[] args)메소드 선언부라고하며, 괄호()바로 앞의 main은 메소드 이름이다.

중괄호{}는 메소드 블록이라고한다.

java 명령어로 바이트 코드 파일을 실행하면 제일 먼저 main() 메소드를 찾아 블록 내부를 실행한다.
그래서 main() 메소드를 프로그램 실행 진입점이라고 한다.

주석 사용하기

  • 주석
    : 프로그램 실행과는 상관없이 코드에 설명을 붙인 것
    : 컴파일 과정에서 무시되고 실행문만 바이트 코드로 변역됨
    -> 주석을 많이 작성한다고해서, 바이트 코드 파일의 크기가 커지는 것은 아님

// = 라인 주석 = //부터 라인 끝까지 주석 처리
/* ... */ = 범위 주석 = /* 와 */사이에 있는 내용 모두 주석 처리
/** .... */ = 도큐먼트 주석 = /** 와 */ 사이에 있는 내용 모두 주석 처리, 주로 javadoc 명령어로 API 도큐먼트를 생성하는데 사용

주석기호는 코드 내 어디서든 작성 가능하나, 문자열 "" 내부에서 작성하면 안된다.
문자열 내부의 주석기호는 문자열 데이터로 인식하기때문이다.

실행문과 세미콜론(;)

실행문 끝에는 반드시 세미콜론(;)을 붙여서 실행문이 끝났음을 표기해야한다.
그렇지않으면 컴파일 에러가 발생한다.

실행문의 종류

  • 변수 선언
  • 값 저장
  • 메소드 호출

컴파일러는 세미콜론까지 하나의 실행문으로 해석
-> 하나의 실행문을 여러 줄에 걸쳐서 작성하고 맨 마지막에 세미콜론을 붙여도 됨
-> 또한 세미콜론을 구분자로 한 줄에 여러가지 실행문을 작성해도 됨

int x =1; int y= 2;
int result = 
x + y;

출처
혼자 공부하는 자바

0개의 댓글