자바 입문 첫걸음 — JVM과 바이트코드가 만드는 이식성의 비밀

자바를 배우기로 마음먹었다면 설치 파일을 내려받기 전에 먼저 알아둘 것이 있습니다. 자바가 어떤 성격의 언어인지, 그리고 왜 “한 번 작성해 어디서나 실행”이라는 문구가 늘 따라다니는지입니다. 이 글에서는 자바의 정체와 실행 구조, 그리고 첫 프로그램의 뼈대가 왜 그렇게 생겼는지를 차례로 살펴봅니다.

자바는 어떤 성격의 언어입니까

자바는 객체 지향 언어입니다. 객체 지향이란 프로그램을 명령의 나열이 아니라 각자 역할을 가진 부품들의 조합으로 바라보는 방식을 말합니다. 카드뉴스 사이트를 만든다면 ‘글 한 편’이라는 부품, ‘작성자’라는 부품을 각각 만들어 두고 이들이 서로 대화하게 하는 식입니다.

또 하나 중요한 성격은 정적 타입입니다. 변수에 어떤 종류의 값이 들어올지 미리 못 박아야 하고, 이를 어기면 실행 전 컴파일 단계에서 곧바로 오류가 납니다. 처음에는 잔소리가 많은 언어처럼 느껴지지만, 코드가 수만 줄로 불어났을 때 이 깐깐함이 사고를 미리 막아 줍니다.

이름 때문에 오해가 잦은데, 자바스크립트는 자바와 이름만 비슷할 뿐 만든 회사도 쓰임새도 문법 계통도 다른 별개의 언어입니다. 둘을 같은 언어의 변형으로 생각하고 공부를 시작하면 계속 혼란스러워집니다.

소스 코드가 실행되기까지 — 바이트코드와 JVM

보통의 언어는 소스 코드를 윈도우용, 맥용처럼 운영체제마다 다른 실행 파일로 번역합니다. 자바는 중간에 한 단계를 더 둡니다. 자바 컴파일러가 .java 파일을 바이트코드라는 중간 언어(.class 파일)로 바꾸고, 이 바이트코드를 JVM(자바 가상 머신)이 읽어서 그 자리에서 기계어로 바꿔 실행합니다.

NoteApp.java   (사람이 쓴 소스 코드)
      ↓  javac (컴파일)
NoteApp.class  (바이트코드 — 운영체제와 무관)
      ↓  java (실행)
윈도우 JVM / 맥 JVM / 리눅스 JVM 이 각자 해석해서 실행

즉 운영체제별 차이를 프로그래머가 아니라 JVM이 떠안습니다. 개발자는 바이트코드 하나만 만들어 두면 JVM이 깔린 곳이면 어디서든 같은 결과가 나옵니다. “한 번 작성해 어디서나 실행”이라는 말은 이 구조를 가리키는 표현입니다. 반대로 말하면 JVM이 없는 환경에서는 자바 프로그램이 한 줄도 돌지 않습니다.

JDK와 JRE는 무엇이 다릅니까

설치 단계에서 가장 먼저 마주치는 약어입니다. 차이는 간단합니다.

구분 포함하는 것 누구에게 필요한가
JRE JVM + 기본 라이브러리 만들어진 자바 프로그램을 실행만 하는 사람
JDK JRE + 컴파일러(javac)와 개발 도구 자바로 코드를 작성하는 사람

정리하면 JDK 안에 JRE가 들어 있고, JRE 안에 JVM이 들어 있는 포함 관계입니다. 강좌를 따라오려면 JDK를 설치하면 됩니다. 실행만 하는 JRE를 깔아 놓고 컴파일이 안 된다며 헤매는 경우가 종종 있습니다.

첫 프로그램의 뼈대를 뜯어봅시다

자바는 코드 한 줄만 달랑 적어서는 실행되지 않습니다. 반드시 클래스 안에, 그중에서도 main 메서드 안에 있어야 합니다.

public class FirstNote {
    public static void main(String[] args) {
        String noteTitle = "카드뉴스 노트 1일차";
        System.out.println(noteTitle);
        System.out.println("자바 강좌를 시작합니다.");
    }
}

한 줄씩 보겠습니다. public class FirstNote는 FirstNote라는 이름의 설계도를 만든다는 선언이고, 이 파일의 이름은 반드시 FirstNote.java여야 합니다. main은 JVM이 프로그램을 시작할 때 가장 먼저 찾아 들어가는 약속된 입구입니다. 이름이나 형태를 마음대로 바꾸면 JVM이 입구를 찾지 못해 실행 자체가 되지 않습니다. System.out.println은 괄호 안의 값을 화면에 출력하고 줄을 바꾸는 명령입니다.

첫날 가장 많이 막히는 지점

자바는 대소문자를 철저히 구분합니다. Stringstring으로, Systemsystem으로 쓰면 그런 이름은 없다는 오류가 납니다. 파일 이름과 public 클래스 이름이 한 글자라도 다르면 컴파일이 거부되는 것도 같은 맥락입니다.

또 하나, 문장 끝의 세미콜론은 장식이 아닙니다. 자바는 줄바꿈이 아니라 ;로 문장의 끝을 판단하기 때문에 하나만 빠져도 그 아래 코드까지 통째로 오류로 번집니다. 오류 메시지에 찍힌 줄 번호보다 한 줄 위를 먼저 확인하는 습관을 들이면 시간이 크게 절약됩니다.

구조를 이해했다면 다음은 값을 담는 그릇을 배울 차례입니다. 자바 변수와 자료형 편에서 이어집니다.

핵심 정리

  • 객체 지향 · 정적 타입 — 역할을 가진 부품으로 프로그램을 짜고, 값의 종류를 미리 선언합니다
  • 바이트코드 — 컴파일 결과물인 .class 파일로, 운영체제에 얽매이지 않습니다
  • JVM — 바이트코드를 해석해 실행하는 가상 머신이며, 이식성의 핵심입니다
  • JDK > JRE > JVM — 개발하려면 JDK, 실행만 하려면 JRE면 충분합니다
  • class와 main — 모든 코드는 클래스 안에 있고, 실행은 main에서 시작합니다