본문으로 건너뛰기

안동민 개발노트

본문 시작

첫 Java 프로그램

Hello.java를 직접 저장하고 javac로 컴파일한 뒤 java로 실행합니다.

첫 프로그램의 목적은 문법을 많이 배우는 것이 아니라 작성 → 컴파일 → 실행의 한 바퀴를 성공시키는 것입니다.

편집기는 메모장, Visual Studio Code, IntelliJ IDEA 등 무엇을 사용해도 됩니다.

다만 서식 있는 문서가 아니라 일반 텍스트로 저장해야 합니다.

Hello.java의 파일, 클래스, main, 출력 문장 포함 관계

NESTED · SOURCE CONTAINMENT

Hello.java를 바깥에서 안쪽으로 읽는 세 범위

코드의 단어를 따로 외우기보다 포함 관계를 따라간다. 파일 안에 공개 클래스가 있고, 그 클래스 안의 main에서 출력 문장이 실행된다.

Hello.java를 바깥에서 안쪽으로 읽는 세 범위 Hello.java 파일이 public class Hello를 포함하고, 그 클래스의 main 메서드 안에 System.out.println 문장이 있으며 세미콜론이 문장을 끝내는 포함 관계다. FILE · Hello.java PUBLIC NAME = FILE NAME public class Hello 가장 바깥 코드 범위 public static void main(String[] args) JVM 진입점 System.out.println("Hello, Java!"); 세미콜론은 이 실행 문장의 종결 표식 FILE ↔ PUBLIC CLASS · JVM CALLS main · println WRITES ONE LINE
  1. 파일 · Hello.java

    파일은 공개 클래스 선언을 담고, 공개 클래스 이름 Hello와 파일명이 정확히 일치합니다.

  2. 클래스 · public class Hello

    첫 중괄호부터 마지막 중괄호까지가 Hello 클래스에 속하는 가장 바깥 코드 범위입니다.

  3. 진입점 · main

    JVM은 클래스 범위 안의 public static void main(String[] args)를 찾아 실행을 시작합니다.

  4. 실행 문장 · println

    main 안의 System.out.println(...);이 문자열 한 줄을 표준 출력에 쓰고, 세미콜론이 문장을 끝냅니다.

포함 관계는 파일 → 클래스 → 메서드 → 문장 순서이며, 각 중괄호 쌍이 어느 범위에 속하는지 먼저 확인한다.


5줄짜리 Hello World

java-board/src 폴더에 Hello.java 파일을 만들고 다음 내용을 그대로 저장합니다.

src/Hello.java — 완전한 파일
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}

처음에는 모든 단어를 외울 필요가 없습니다.

각 줄의 역할은 다음과 같습니다.

  • public class HelloHello라는 프로그램 단위를 선언합니다.
  • {와 마지막 }Hello에 속하는 범위를 표시합니다.
  • main은 프로그램이 시작할 위치입니다.
  • System.out.println(...)은 괄호 안의 글을 한 줄 출력합니다.
  • 세미콜론 ;은 출력 문장이 끝났음을 표시합니다.

Java는 대소문자를 구분합니다.

hello, Hello, HELLO는 서로 다른 이름입니다.

공개 클래스 이름이 Hello이므로 파일명도 정확히 Hello.java여야 합니다.


컴파일하기

PowerShell이 java-board 폴더에 있는지 확인한 뒤 다음 명령을 실행합니다.

javac -d out src/Hello.java

아무 메시지도 나오지 않으면 컴파일에 성공한 것입니다.

성공한 명령이 조용히 끝나는 것은 이상한 일이 아닙니다.

out 폴더를 확인합니다.

Get-ChildItem out
Hello.class

Hello.java는 사람이 편집하는 소스 파일이고 Hello.classjavac가 만든 실행용 파일입니다.

.class를 편집하지 않습니다.


실행하기

다음 명령에서 -cp out은 실행할 클래스를 out 폴더에서 찾으라는 뜻입니다.

마지막 Hello는 파일 경로가 아니라 실행할 클래스 이름이므로 .class를 붙이지 않습니다.

java -cp out Hello
Hello, Java!

이 출력이 보이면 작성·컴파일·실행 세 단계가 모두 성공했습니다.

src/Hello.java  --javac-->  out/Hello.class  --java-->  화면 출력

소스를 바꾸면 다시 컴파일한다

출력 문자열을 다음처럼 바꿔 저장합니다.

System.out.println("회원가입 시작");

java 명령만 다시 실행하면 이전 출력이 나옵니다.

JVM은 방금 고친 .java 파일이 아니라 기존 Hello.class를 실행하기 때문입니다.

먼저 다시 컴파일한 뒤 실행합니다.

javac -d out src/Hello.java
java -cp out Hello
회원가입 시작

IDE의 실행 버튼은 저장과 컴파일을 대신 처리할 수 있습니다.

이 교재에서는 각 단계가 보이도록 처음에는 터미널 명령을 사용합니다.

Hello 소스와 class의 신선도 및 실행 흐름

FLOWCHART · ARTIFACT FRESHNESS

java는 최신 소스가 아니라 마지막 class를 실행한다

소스를 저장하는 일과 class를 갱신하는 일은 별개다. java는 out에서 발견한 마지막 class를 실행하므로 재컴파일을 생략하거나 실패하면 이전 출력이 남을 수 있다.

java는 최신 소스가 아니라 마지막 class를 실행한다 Hello.java를 저장한 뒤 javac 성공 여부에 따라 Hello.class가 갱신되거나 기존 상태를 유지하고, java가 out에서 발견한 class의 main을 호출해 그 class 상태에 해당하는 출력을 만드는 흐름이다. src/Hello.java 수정 · 저장 소스 상태만 먼저 바뀜 javac가 성공했나? 마지막 저장 이후 class는 갱신되지 않음 기존 class 유지 · 최초면 아직 없음 미실행·실패 out/Hello.class 갱신 JVM bytecode · 현재 소스 반영 성공 java -cp out Hello out = classpath root · Hello = binary name JVM이 발견한 class의 main 호출 표준 출력은 class의 신선도를 반영 OLD OUTPUT CAN MEAN: SOURCE CHANGED AFTER THE LAST SUCCESSFUL COMPILE
  1. 소스 수정과 저장

    src/Hello.java를 저장하면 소스만 바뀌며 out/Hello.class는 자동으로 갱신되지 않습니다.

  2. javac 성공 여부

    javac -d out src/Hello.java가 성공해야 class가 현재 소스를 반영합니다. 명령을 생략하거나 실패하면 기존 class가 남고, 최초라면 class가 아직 없습니다.

  3. classpath에서 class 탐색

    java -cp out Hello에서 out은 classpath root이고 Hello는 확장자가 없는 binary class name입니다.

  4. JVM 진입

    java launcher가 JVM을 시작하고, JVM은 발견한 class의 main을 호출해 표준 출력을 만듭니다.

  5. 오래된 출력 해석

    오류 없이 이전 문구가 보이면 마지막 성공 컴파일 이후 소스만 바뀌었는지 확인합니다. java는 최신 .java를 직접 읽지 않습니다.

컴파일 실패 뒤에도 이전 .class가 남을 수 있으므로, 실행 성공만으로 최신 소스가 반영됐다고 단정하지 않는다.


첫 소스를 읽는 순서

긴 선언을 한 덩어리로 외우기보다 바깥에서 안쪽으로 읽습니다.

  1. class Hello: Hello라는 클래스의 범위
  2. main: 실행이 시작되는 메서드의 범위
  3. println: 실제로 실행할 출력 문장

클래스와 메서드가 정확히 무엇인지는 뒤 장에서 작은 예제로 다시 배웁니다.

지금은 중괄호의 짝과 문장의 실행 순서를 확인합니다.


연습 문제

src/NewMember.java를 만들고 가입할 이메일과 역할을 두 줄로 출력하세요.

출력 예
email=kim@example.com
role=member

파일명과 공개 클래스 이름을 NewMember로 맞추고 다음 명령으로 확인합니다.

javac -d out src/NewMember.java
java -cp out NewMember