JAVA · 심층 가이드
Java Hello World 완전 정리
JDK 설치부터 main 메서드 규칙, Maven과 Gradle 프로젝트 구조, LTS 버전 선택 기준까지 첫 Java 코드를 실행 가능한 상태로 만드는 5개 주제입니다.
Java의 첫 관문은 문법이 아니라 실행 환경입니다. 소스 파일 이름과 public 클래스 이름이 같아야 하고, 패키지 선언은 디렉터리 구조와 일치해야 하며, 진입점은 정해진 시그니처의 main이어야 합니다. 이 규약을 모르면 컴파일 오류 메시지가 무엇을 말하는지조차 알기 어렵습니다. 반대로 Java 11부터는 java Hello.java처럼 단일 소스 파일을 컴파일 없이 바로 실행할 수 있어서, 학습 단계에서는 빌드 도구 없이도 충분히 굴려 볼 수 있습니다.
그래서 Hello World — 클래식 & 최신 문법으로 진입점과 출력 방식을 먼저 확인하고, JDK 버전 선택과 프로젝트 구조에서 LTS를 고르는 기준과 src/main/java 관례를 잡는 순서를 권합니다. 그 뒤에 Maven 프로젝트 설정과 Gradle 프로젝트 설정 중 하나를 골라 의존성 관리를 붙이면 됩니다. 둘 중 어느 쪽을 쓰든 디렉터리 관례는 같으므로, 나중에 다른 도구로 옮기는 비용은 생각보다 작습니다. var & 타입 추론은 문법이 손에 익은 뒤 읽어도 늦지 않습니다.
초반에 가장 많이 새는 시간은 버전 불일치입니다. 터미널의 java -version, IDE가 물고 있는 SDK, 빌드 파일에 적힌 컴파일 타깃이 제각각이면 IDE에서는 멀쩡한 코드가 명령줄 빌드에서 깨집니다. Maven이라면 maven.compiler.source와 target을 따로 두는 대신 maven.compiler.release 하나로 지정하는 편이 안전합니다. 이 옵션은 그 버전의 표준 API 시그니처까지 함께 검사해 주기 때문에, 낮은 버전을 타깃으로 하면서 상위 버전 API를 쓰는 사고를 컴파일 시점에 막아 줍니다.
01Hello World — 클래식 & 최신 문법
Java의 전통적인 Hello World부터 Java 21의 간결한 문법까지. 엔트리포인트와 출력 방법을 마스터합니다.
Java code
// 전통적인 방법 (Java 1 ~ 현재)
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
// 포맷 출력
String name = "Java";
int version = 21;
System.out.printf("언어: %s, 버전: %d%n", name, version);
// String.format
String msg = String.format("Hello, %s %d!", name, version);
System.out.println(msg);
// formatted() — Java 15+
String msg2 = "Hi, %s!".formatted(name);
System.out.println(msg2);
}
}
// Java 21 — Unnamed Class (Preview)
// 파일명: Hello.java
// void main() {
// System.out.println("Hello from Java 21!");
// }
// Text Block (Java 15+)
// String json = """
// {
// "language": "Java",
// "version": 21
// }
// """;System.out.println()은 개행 포함, print()는 개행 없음, printf()는 포맷 지정입니다. %n은 OS에 맞는 개행 문자를 사용합니다.
파일명은 반드시 public class 이름과 동일해야 합니다. HelloWorld.java가 아닌 파일명은 컴파일 에러입니다.
02var & 타입 추론 (Java 10+)
Java 10에 추가된 지역 변수 타입 추론 var로 코드를 간결하게 작성합니다.
Java code
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class VarExample {
public static void main(String[] args) {
// var — 지역 변수에서만 사용
var name = "Java"; // String 추론
var version = 21; // int 추론
var pi = 3.14159; // double 추론
var active = true; // boolean 추론
// 컬렉션에서 특히 유용
var list = new ArrayList<String>();
list.add("Hello");
list.add("World");
// for-each에서도 사용 가능
for (var item : list) {
System.out.println(item);
}
// Map.entry 순회 시 매우 편리
var map = Map.of("a", 1, "b", 2, "c", 3);
for (var entry : map.entrySet()) {
System.out.printf("%s = %d%n",
entry.getKey(), entry.getValue());
}
// 컴파일러가 실제 타입을 추론 — 런타임에 타입 보존
System.out.println(((Object)name).getClass().getName());
}
}var는 컴파일 타임 타입 추론입니다. 런타임에 실제 타입이 보존됩니다. 복잡한 제네릭 타입 선언을 줄일 때 특히 유용합니다.
var는 지역 변수에서만 사용 가능합니다. 인스턴스 필드, 메서드 파라미터, 반환 타입에는 사용할 수 없습니다.
03Maven 프로젝트 설정
Maven pom.xml로 Java 프로젝트를 구성하고 의존성을 관리하는 방법입니다.
Java code
<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>mvn archetype:generate로 프로젝트 템플릿을 빠르게 생성할 수 있습니다. mvn clean package로 빌드합니다.
maven.compiler.source와 target 버전이 다르면 호환성 문제가 발생합니다. 항상 동일하게 맞추세요.
04Gradle 프로젝트 설정
Gradle build.gradle로 Java 프로젝트를 구성합니다. Kotlin DSL도 함께 살펴봅니다.
Java code
// build.gradle (Groovy DSL)
plugins {
id 'java'
id 'application'
}
group = 'com.example'
version = '1.0-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
}
application {
mainClass = 'com.example.Main'
}
tasks.named('test') {
useJUnitPlatform()
}Gradle Wrapper(gradlew)를 사용하면 Gradle 버전을 프로젝트에 고정할 수 있어 팀 협업 시 유리합니다.
Groovy DSL과 Kotlin DSL(build.gradle.kts)의 문법이 다릅니다. 프로젝트에서 하나를 통일해서 사용하세요.
05JDK 버전 선택과 프로젝트 구조
LTS 버전 선택 기준과 표준 Maven/Gradle 디렉토리 구조를 이해합니다.
Java code
// 표준 프로젝트 구조
// my-app/
// src/
// main/
// java/
// com/example/
// Main.java
// resources/
// application.properties
// test/
// java/
// com/example/
// MainTest.java
// resources/
// Main.java
package com.example;
public class Main {
public static void main(String[] args) {
// JDK 버전 확인
String ver = System.getProperty("java.version");
System.out.println("JDK Version: " + ver);
// Runtime 정보
Runtime rt = Runtime.getRuntime();
System.out.printf("CPU: %d, Memory: %dMB%n",
rt.availableProcessors(),
rt.maxMemory() / 1024 / 1024);
}
}LTS 버전(17, 21, 25)을 선택하세요. LTS는 최소 8년간 보안 업데이트를 받을 수 있습니다. 상용 환경에서는 반드시 LTS를 사용하세요.
Java 8에서 21로 바로 마이그레이션하면 javax → jakarta 네임스페이스 변경 등 큰 차이가 있으므로 단계적으로 진행하세요.
정리하며
- 파일명·public 클래스명·패키지 경로 세 가지가 일치해야 컴파일이 통과합니다
- Java 11+에서는 java Hello.java로 단일 파일을 바로 실행해 빌드 도구 없이 연습할 수 있습니다
- Maven은 source/target 대신 release 속성 하나로 지정해 API 오사용을 컴파일 때 잡습니다
- 터미널 JDK, IDE SDK, 빌드 파일 타깃 버전을 처음에 한 번에 맞춰 두면 이후 삽질이 줄어듭니다
더 깊이 들어가고 싶다면 Java 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.