사전 Java SE
표준

Java SE

gabury1고친 사람 github-actions[bot]

Java SE 는 자바로 짠 프로그램이 어느 컴퓨터에서나 같게 돌도록 미리 맞춰 둔 약속입니다. 자바 한 벌에 무엇이 들어가야 하는지를 문서로 정해 둡니다. 자바를 깔아 쓰는 사람이 내려받는 것은 이 약속대로 만들어 놓은 꾸러미입니다.

쉽고 빠른 이해

Java SE 는 자바 한 벌이 무엇으로 이루어지는지를 적어 둔 규격입니다. 어느 꾸러미를 깔든 List 나 String 같은 이름이 같은 모양으로 그대로 들어 있는 것이 이 규격 덕입니다.

규격이 없으면 만드는 곳마다 문법과 라이브러리가 갈립니다. 그러면 내가 짠 코드가 내 컴퓨터에 깔린 자바에서만 돌고, 다른 데로 옮길 때마다 고쳐야 합니다.

어떻게 도나:

  1. 문서 세 벌이 언어 문법과 실행기 동작과 기본 라이브러리 목록을 정합니다
  2. 여러 회사와 재단이 그 문서를 보고 각자 꾸러미를 만들어 내놓습니다
  3. 그 꾸러미는 정해진 시험을 통과해야 자바와 호환된다고 내세울 수 있습니다

대가는 한번 들어간 것을 빼기 어렵다는 점입니다. 옛 코드가 계속 돌아야 하므로 잘못 지은 이름도 오래 남고, 새것은 대개 그 옆에 하나 더 생기는 꼴로 들어옵니다.

상세

Java SE 는 깔아서 쓰는 프로그램이 아니라 문서 묶음입니다. 자바를 깔 때 내려받는 꾸러미는 그 문서를 따라 만든 물건입니다. 이 절은 그 문서가 무엇을 정하는지 보고, 문서와 꾸러미를 가르는 선을 긋습니다.

자바 표준판이라는 이름

Java SE 는 Java Platform, Standard Edition 을 줄인 이름입니다. 우리말로 옮기면 자바 플랫폼 표준판입니다. 「표준」이 붙은 까닭은 자바 플랫폼에 판이 여럿 있어서입니다. 그중 데스크톱과 서버에서 쓰는 판이 이것입니다.

이 이름이 가리키는 것은 프로그램이 아니라 문서 묶음입니다. 콘센트 규격과 벽에 박힌 콘센트의 사이입니다. 규격은 읽는 것입니다. 손에 잡히는 쪽은 그것을 따라 만든 꾸러미입니다.

규격을 따로 세워 둔 까닭은 자바를 만들어 내놓는 곳이 하나가 아니기 때문입니다. 오라클 · 이클립스 재단 · 아마존처럼 여러 곳이 각자 꾸러미를 만들어 배포합니다. 그래도 문법과 라이브러리가 갈리지 않게 붙잡아 주는 것이 이 문서 묶음입니다.

규격을 이루는 문서 세 벌

Java SE 규격은 다루는 것이 서로 다른 문서 세 벌로 이루어집니다.

첫째는 자바 언어 명세입니다. 무엇이 올바른 자바 소스인지, 그 소스가 어떤 동작을 뜻하는지를 정합니다. for 문이 어떻게 생겼는지, 정수끼리 나눌 때 소수점 아래를 어떻게 버리는지가 여기서 정해집니다.

둘째는 JVM 명세입니다. JVM 은 Java Virtual Machine 을 줄인 이름으로, 자바 프로그램을 대신 돌려 주는 가상의 기계입니다. 이 문서는 그 기계가 받는 것과 알아듣는 말을 정합니다.

받는 것은 소스를 컴파일해서 나온 클래스 파일입니다. 그 바이트가 어떤 모양이어야 하는지가 이 문서에 적혀 있습니다. 알아듣는 말은 바이트코드입니다. JVM 이 실행할 수 있는 명령 목록을 그렇게 부릅니다.

셋째는 기본 라이브러리 명세입니다. 표준 라이브러리라고도 부릅니다. 자바를 깔면 따라오는 이름들의 목록입니다.

각 이름이 무엇을 약속하는지를 이 문서가 정합니다. java.util.List 처럼 아무것도 내려받지 않고 바로 부를 수 있는 것이 전부 여기 적혀 있습니다.

문서가 셋으로 갈린 까닭은 자바가 소스를 곧바로 돌리지 않고 중간에 한 번 끊기 때문입니다. 소스를 클래스 파일로 옮기는 앞 구간과 그 파일을 받아 돌리는 뒤 구간이 서로 다른 문서에 적혀 있습니다. 라이브러리 명세는 양쪽이 같이 봅니다.

flowchart TD
    subgraph 앞구간["앞 구간 · 소스를 클래스 파일로"]
        S["소스"] --> C["클래스 파일"]
    end
    subgraph 뒤구간["뒤 구간 · 클래스 파일을 돌린다"]
        R["JVM 이 명령을 하나씩 실행"]
    end
    C --> R
    L["자바 언어 명세"] --> 앞구간
    V["JVM 명세"] --> 뒤구간
    A["기본 라이브러리 명세"] --> 앞구간
    A --> 뒤구간

규격과 꾸러미를 가르는 선

자바를 처음 만나면 비슷하게 생긴 이름 넷이 한꺼번에 나옵니다. 깔아 쓰는 쪽에 JDK(Java Development Kit, 자바 개발 키트)·JRE(Java Runtime Environment, 자바 실행 환경)·JVM 셋이 더 있기 때문입니다.

이름 무엇인가 깔 수 있나
Java SE 지켜야 할 내용을 적어 둔 규격 문서라서 못 깐다
JDK 규격대로 만들어 내놓은 꾸러미. 컴파일러와 실행기가 다 들어 있다 깐다
JRE JDK 에서 개발 도구를 뺀, 돌리기만 하는 꾸러미 깐다
JVM 꾸러미 안에서 프로그램을 실제로 돌리는 실행기 JDK 에 들어 있다

넷은 나란히 선 것이 아니라 하나가 다른 하나를 품고 있습니다.

flowchart TD
    SPEC["Java SE · 규격 · 문서"]
    subgraph JDK["JDK · 꾸러미"]
        TOOLS["javac 등 개발 도구"]
        subgraph JRE["JRE · 돌리기만 하는 꾸러미"]
            JVMBOX["JVM · 실행기"]
            LIB["기본 라이브러리"]
        end
    end
    SPEC -->|"따라 만든다"| JDK

JDK 를 깔면 JRE 가 딸려 옵니다. 그 안에 JVM 과 기본 라이브러리가 들어 있습니다.

표의 첫 줄만 성격이 다릅니다. 「Java SE 를 깔았다」는 말은 대개 OpenJDK 계열 배포판 하나를 깔았다는 뜻입니다. 여기서 배포판은 앞에서 말한 꾸러미와 같은 말입니다.

규격 자체는 내려받아 읽는 문서입니다. 손에 잡히는 것은 언제나 그 꾸러미입니다.

같은 코드가 여러 기계에서 도는 까닭

자바는 한 번 컴파일해 두면 운영체제를 안 가리고 돈다고 내세웁니다. 이 성질은 두 가지가 같이 받쳐 줍니다.

하나는 컴파일 결과입니다. javac 가 내놓는 클래스 파일은 특정 기계의 기계어가 아니라 어느 기계에도 안 매인 명령으로 채워집니다. 그 파일을 이 기계에서 돌게 만드는 일은 JVM 이 맡습니다.

flowchart TD
    S["소스 코드"] --> C["클래스 파일 · 어느 기계에도 안 매인 명령"]
    C --> W["윈도의 JVM"]
    C --> L["리눅스의 JVM"]
    C --> M["맥의 JVM"]

컴파일은 한 번만 합니다. 갈라지는 대목은 그 뒤입니다. 운영체제마다 다른 것은 클래스 파일이 아니라 그것을 받아 돌리는 JVM 쪽입니다.

다른 하나는 이름입니다. 코드가 부르는 이름은 어느 꾸러미에서나 같습니다. 기본 라이브러리 명세가 그 이름과 동작을 미리 정해 두기 때문입니다.

Java
List<String> names = List.of("a", "b");  // java.util.List
System.out.println(names.size());        // 2

이 두 줄은 어느 꾸러미에서 돌려도 같은 값을 냅니다. List 라는 이름이 어디에 있고 size() 가 무엇을 돌려주는지가 규격에 적혀 있어서입니다.

약속을 지켰는지는 호환성 시험으로 가립니다. 꾸러미를 만든 쪽은 정해진 시험 묶음을 받아 돌려 봅니다. 통과해야 자바와 호환된다고 내세울 수 있습니다. 이 시험 묶음을 TCK(Technology Compatibility Kit, 기술 호환성 시험 도구)라고 부릅니다.

flowchart TD
    SPEC["Java SE 규격 · 문서"] --> IMPL["여러 곳이 각자 만든 꾸러미"]
    IMPL --> TCK["TCK · 정해진 시험 묶음"]
    TCK -->|"통과"| OK["자바와 호환된다고 내세운다"]
    TCK -->|"못 통과"| NO["자바라는 이름을 못 쓴다"]

새 버전에서도 옛 코드가 도는 까닭

Java SE 는 버전을 올리면서도 옛것을 버리지 않는 쪽을 골라 왔습니다. 오래전에 컴파일해 둔 클래스 파일을 새 실행기가 대개 그대로 읽습니다. 예전 버전을 보고 짠 소스도 새 컴파일러가 대개 받아 줍니다. 이런 성질을 하위 호환이라고 부릅니다.

그래서 새 버전에 들어오는 것은 거의 더하기입니다. 쓸 수 있는 이름을 늘리고 문법을 새로 얹되, 이미 있던 것의 뜻은 바꾸지 않습니다.

빼는 일은 아주 느리게 일어납니다. 지우고 싶은 이름에는 먼저 이제 쓰지 말라는 표시를 답니다. 그 상태로 오래 남겨 둡니다. 쓰던 코드가 다 옮겨 갔다고 볼 만할 때에야 뺍니다.

stateDiagram-v2
    state "쓰는 이름" as A
    state "이제 쓰지 말라는 표시가 붙은 이름" as B
    state "빠진 이름" as C
    [*] --> A
    A --> B: 고친 이름이 옆에 새로 생겼다
    B --> C: 쓰던 코드가 다 옮겨 갔다

이것이 Java SE 가 치르는 대가입니다. 한번 규격에 들어간 이름은 잘못 지었어도 오래 남습니다. 고친 것은 그 옆에 새 이름으로 하나 더 생깁니다. 비슷한 일을 하는 이름이 라이브러리에 여럿 보이는 까닭이 이것입니다.

Java SE 밖으로 밀려나 있는 기능

백엔드에서 자바로 하는 일이 전부 이 규격 안에 있지는 않습니다. 밖에 있는 것을 알아 두면 필요한 것을 어디서 찾을지가 분명해집니다.

Jakarta EE(Enterprise Edition, 기업용 판)는 Java SE 위에 얹혀 도는 규격입니다. 웹 요청을 받고 트랜잭션을 걸고 메시지를 주고받는 서버 기능을 여기서 맡습니다. Java SE 꾸러미 위에서 도는 것이라 Java SE 를 대신하지 않습니다.

Java ME(Micro Edition, 소형 기기용 판)는 옆에 선 다른 판입니다. 손바닥만 한 기기에 넣으려고 잘라 낸 것이라 Java SE 와 위아래 관계가 아닙니다.

규격이 안 담는 것 어디가 받나
웹 요청 처리·트랜잭션 관리 같은 서버 기능 Jakarta EE
소형 기기에 맞춰 잘라 낸 실행 환경 Java ME
라이브러리 내려받기와 빌드 Maven·Gradle 같은 빌드 도구

마지막 줄이 실무에서 제일 자주 걸립니다. 자바를 깔아도 남이 만든 라이브러리를 받아 오는 수단은 딸려 오지 않습니다. 그 일은 빌드 도구가 따로 맡습니다.

Android 도 이 선 밖에 있습니다. 자바 문법으로 짜기는 하지만 실행기와 라이브러리가 달라서 Java SE 를 구현한 것이 아닙니다. 그래서 규격 문서에 있는 이름이 안드로이드에는 없는 일이 생깁니다.

flowchart TD
    EE["Jakarta EE · 서버 기능"]
    subgraph SE["Java SE · 선 안"]
        LANG["언어 문법"]
        JVMIN["JVM"]
        LIBIN["기본 라이브러리"]
    end
    ME["Java ME · 옆에 선 다른 판"]
    subgraph OUT["선 밖"]
        AND["Android"]
        BUILD["Maven · Gradle 같은 빌드 도구"]
    end
    EE -->|"위에 얹혀 돈다"| SE
    SE --- ME
    SE --- OUT

관련 항목

Java SE 규격을 이루는 문서

자바 언어 명세 · JVM 명세 · 표준 라이브러리 · 클래스 파일 · 바이트코드

Java SE 를 구현해 내려받게 만든 배포판

JDK · JRE · OpenJDK · Eclipse Temurin · Amazon Corretto

Java SE 규격이 정한 실행 장치

JVM · 가상 머신 · 클래스 로더 · 클래스패스 · 가비지 컬렉션

Java SE 코드를 컴파일하고 들여다보는 명령

javac · javap · java 명령 · jar 명령 · jlink

Java SE 밖에서 서버 기능을 맡는 규격과 틀

Jakarta EE · 서블릿 · Spring · 애플리케이션 서버 · Java ME

Java SE 를 딛고 도는 다른 언어

Kotlin · Scala · Groovy · Clojure · kotlinc

Java SE 가 버전을 올리며 지키는 약속

하위 호환 · 호환성 시험 · 디프리케이션 · 상호운용성

Java SE 프로그램을 묶어 내보내는 산출물

JAR · WAR · 아티팩트 저장소 · Maven · Gradle

Java SE 가 속하는 상위 분류

Java · 프로그래밍 언어 · 런타임 · 표준 · 플랫폼

다른 이름: 자바 SE · 자바 표준판 · Java Platform Standard Edition