Java 시작하기 | JDK 설치부터 Hello World까지
이 글의 핵심
Java 시작하기에 대한 실전 가이드입니다. JDK 설치부터 Hello World까지 등을 예제와 함께 상세히 설명합니다.
들어가며
”한 번 작성하면 어디서나 실행”
Java는 1995년 Sun Microsystems(현 Oracle)가 내놓은 객체지향(데이터와 동작을 객체로 묶어 설계하는 방식) 언어입니다. Write Once, Run Anywhere(WORA)는 같은 바이트코드를 JVM(자바 바이트코드를 실행하는 가상 머신)이 있는 환경에서 실행한다는 뜻입니다.
클래스는 객체의 설계도, 인스턴스는 그 설계도로 만든 실체라는 관점이 이후 글 전체와 연결됩니다.
Java의 핵심 특징:
- ✅ 플랫폼 독립적: JVM(Java Virtual Machine)에서 실행
- ✅ 객체지향: 모든 것이 객체 (클래스 기반)
- ✅ 가비지 컬렉션: 자동 메모리 관리
- ✅ 강력한 타입: 정적 타입 언어 (컴파일 타임 체크)
- ✅ 풍부한 라이브러리: 방대한 표준 라이브러리와 생태계
- ✅ 멀티스레딩: 내장 스레드 지원
- ✅ 보안: 샌드박스 모델
Java가 사용되는 곳:
- 🏢 엔터프라이즈: Spring Framework, 대규모 서버
- 📱 Android: Android 앱 개발
- 🌐 웹: JSP, Servlet, Spring Boot
- 📊 빅데이터: Hadoop, Spark
- 🎮 게임: Minecraft
1. JDK 설치
JDK vs JRE vs JVM
| 구분 | 설명 | 포함 |
|---|---|---|
| JVM | Java Virtual Machine (실행 엔진) | 바이트코드 실행 |
| JRE | Java Runtime Environment (실행 환경) | JVM + 라이브러리 |
| JDK | Java Development Kit (개발 도구) | JRE + 컴파일러(javac) + 디버거 |
개발자는 JDK 설치 필수!
Windows 설치
1. JDK 다운로드:
- Oracle JDK (상용 라이선스)
- OpenJDK (무료, 권장)
2. 설치:
# 다운로드한 설치 프로그램 실행
# 설치 경로: C:\Program Files\Java\jdk-21
# 환경 변수 자동 설정 (또는 수동)
JAVA_HOME=C:\Program Files\Java\jdk-21
PATH=%JAVA_HOME%\bin;%PATH%
3. 설치 확인:
java -version
# 출력:
# openjdk version "21.0.1" 2023-10-17
# OpenJDK Runtime Environment (build 21.0.1+12-29)
# OpenJDK 64-Bit Server VM (build 21.0.1+12-29, mixed mode, sharing)
javac -version
# 출력:
# javac 21.0.1
macOS 설치
# Homebrew 사용
brew install openjdk@21
# 심볼릭 링크 생성
sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk \
/Library/Java/JavaVirtualMachines/openjdk-21.jdk
# 확인
java -version
Linux 설치
# Ubuntu/Debian
sudo apt update
sudo apt install openjdk-21-jdk
# CentOS/RHEL
sudo yum install java-21-openjdk-devel
# 확인
java -version
javac -version
2. Hello World
HelloWorld.java 작성
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
코드 설명:
public class HelloWorld: 공개 클래스 선언 (파일명과 동일해야 함)public static void main(String[] args): 프로그램 진입점public: 어디서나 접근 가능static: 객체 생성 없이 호출 가능void: 반환값 없음String[] args: 명령줄 인자
System.out.println(): 콘솔 출력
컴파일 및 실행
# 1. 컴파일 (javac)
javac HelloWorld.java
# → HelloWorld.class 생성 (바이트코드)
# 2. 실행 (java)
java HelloWorld
# 출력: Hello, Java!
동작 원리:
HelloWorld.java (소스 코드)
↓ javac (컴파일)
HelloWorld.class (바이트코드)
↓ java (실행)
JVM (플랫폼별 실행)
↓
출력: Hello, Java!
명령줄 인자
public class Args {
public static void main(String[] args) {
System.out.println("인자 개수: " + args.length);
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
javac Args.java
java Args 안녕 자바 123
# 출력:
# 인자 개수: 3
# args[0]: 안녕
# args[1]: 자바
# args[2]: 123
3. IDE 설정
IntelliJ IDEA (권장)
1. 다운로드:
2. 프로젝트 생성:
File → New → Project
- Name: MyFirstJavaProject
- Language: Java
- Build System: IntelliJ
- JDK: 21
3. 실행:
- 단축키:
Shift + F10(Run) - 디버그:
Shift + F9
Eclipse
1. 다운로드:
2. 프로젝트 생성:
File → New → Java Project
- Project name: MyFirstJavaProject
- JRE: Use default JRE
VS Code
1. 확장 설치:
- Extension Pack for Java
2. 프로젝트 생성:
# 명령 팔레트 (Ctrl+Shift+P)
Java: Create Java Project
4. 기본 문법
변수와 타입
public class Variables {
public static void main(String[] args) {
// 기본 타입 (Primitive Types)
byte b = 127; // 8비트 (-128 ~ 127)
short s = 32767; // 16비트
int age = 25; // 32비트 (기본)
long population = 7800000000L; // 64비트 (L 접미사)
float pi = 3.14f; // 32비트 (f 접미사)
double price = 19.99; // 64비트 (기본)
boolean isActive = true; // true/false
char grade = 'A'; // 16비트 유니코드
// 참조 타입 (Reference Types)
String name = "홍길동";
String message = "안녕하세요!";
// 출력
System.out.println("이름: " + name);
System.out.println("나이: " + age);
System.out.println("가격: " + price);
}
}
상수
public class Constants {
public static void main(String[] args) {
// final: 변경 불가
final int MAX_SIZE = 100;
final double PI = 3.14159;
final String APP_NAME = "MyApp";
// MAX_SIZE = 200; // 컴파일 에러!
System.out.println("최대 크기: " + MAX_SIZE);
}
}
연산자
public class Operators {
public static void main(String[] args) {
// 산술 연산자
int a = 10, b = 3;
System.out.println("더하기: " + (a + b)); // 13
System.out.println("빼기: " + (a - b)); // 7
System.out.println("곱하기: " + (a * b)); // 30
System.out.println("나누기: " + (a / b)); // 3 (정수 나눗셈)
System.out.println("나머지: " + (a % b)); // 1
// 비교 연산자
System.out.println(a > b); // true
System.out.println(a == b); // false
System.out.println(a != b); // true
// 논리 연산자
boolean x = true, y = false;
System.out.println(x && y); // false (AND)
System.out.println(x || y); // true (OR)
System.out.println(!x); // false (NOT)
// 증감 연산자
int count = 0;
count++; // count = count + 1
System.out.println(count); // 1
count--; // count = count - 1
System.out.println(count); // 0
}
}
조건문
public class Conditionals {
public static void main(String[] args) {
int score = 85;
// if-else
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else {
System.out.println("F");
}
// switch
String day = "월요일";
switch (day) {
case "월요일":
System.out.println("월요일입니다.");
break;
case "금요일":
System.out.println("금요일입니다!");
break;
default:
System.out.println("평일입니다.");
}
// 삼항 연산자
String result = (score >= 60) ? "합격" : "불합격";
System.out.println(result);
}
}
반복문
public class Loops {
public static void main(String[] args) {
// for 문
for (int i = 0; i < 5; i++) {
System.out.println("i = " + i);
}
// while 문
int count = 0;
while (count < 3) {
System.out.println("count = " + count);
count++;
}
// do-while 문
int num = 0;
do {
System.out.println("num = " + num);
num++;
} while (num < 3);
// 배열 순회
int[] numbers = {1, 2, 3, 4, 5};
for (int n : numbers) {
System.out.println(n);
}
}
}
5. 함수 (메서드)
메서드 정의
public class Calculator {
// 반환값 있는 메서드
public static int add(int a, int b) {
return a + b;
}
// 반환값 없는 메서드
public static void printSum(int a, int b) {
System.out.println("합계: " + (a + b));
}
// 오버로딩 (같은 이름, 다른 매개변수)
public static int add(int a, int b, int c) {
return a + b + c;
}
public static double add(double a, double b) {
return a + b;
}
public static void main(String[] args) {
int result1 = add(10, 20);
System.out.println("결과1: " + result1); // 30
int result2 = add(10, 20, 30);
System.out.println("결과2: " + result2); // 60
double result3 = add(10.5, 20.3);
System.out.println("결과3: " + result3); // 30.8
printSum(5, 7); // 합계: 12
}
}
가변 인자
public class VarArgs {
public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
public static void main(String[] args) {
System.out.println(sum(1, 2, 3)); // 6
System.out.println(sum(1, 2, 3, 4, 5)); // 15
System.out.println(sum(10)); // 10
}
}
6. 클래스와 객체
클래스 정의
public class Person {
// 필드 (멤버 변수)
private String name;
private int age;
// 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 기본 생성자
public Person() {
this("이름없음", 0);
}
// 메서드
public void introduce() {
System.out.println("안녕하세요, " + name + "입니다.");
System.out.println("나이는 " + age + "세입니다.");
}
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 0) {
this.age = age;
}
}
}
객체 생성 및 사용
public class Main {
public static void main(String[] args) {
// 객체 생성
Person person1 = new Person("홍길동", 25);
Person person2 = new Person("김철수", 30);
Person person3 = new Person();
// 메서드 호출
person1.introduce();
// 출력:
// 안녕하세요, 홍길동입니다.
// 나이는 25세입니다.
person2.introduce();
// Getter/Setter 사용
System.out.println("이름: " + person1.getName());
person1.setAge(26);
System.out.println("새 나이: " + person1.getAge());
}
}
7. 배열
배열 선언 및 초기화
public class Arrays {
public static void main(String[] args) {
// 배열 선언 방법 1
int[] numbers1 = new int[5];
numbers1[0] = 10;
numbers1[1] = 20;
// 배열 선언 방법 2
int[] numbers2 = {1, 2, 3, 4, 5};
// 배열 선언 방법 3
int[] numbers3 = new int[]{10, 20, 30};
// 배열 길이
System.out.println("길이: " + numbers2.length); // 5
// 배열 순회
for (int i = 0; i < numbers2.length; i++) {
System.out.println("numbers2[" + i + "] = " + numbers2[i]);
}
// 향상된 for 문
for (int num : numbers2) {
System.out.println(num);
}
// 2차원 배열
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(matrix[1][2]); // 6
}
}
8. 실전 예제
예제 1: 계산기
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("첫 번째 숫자: ");
double num1 = scanner.nextDouble();
System.out.print("연산자 (+, -, *, /): ");
String operator = scanner.next();
System.out.print("두 번째 숫자: ");
double num2 = scanner.nextDouble();
double result = 0;
switch (operator) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
if (num2 != 0) {
result = num1 / num2;
} else {
System.out.println("0으로 나눌 수 없습니다.");
return;
}
break;
default:
System.out.println("잘못된 연산자입니다.");
return;
}
System.out.println("결과: " + result);
scanner.close();
}
}
예제 2: 학생 관리
public class Student {
private String name;
private int studentId;
private double gpa;
public Student(String name, int studentId, double gpa) {
this.name = name;
this.studentId = studentId;
this.gpa = gpa;
}
public void printInfo() {
System.out.println("=== 학생 정보 ===");
System.out.println("이름: " + name);
System.out.println("학번: " + studentId);
System.out.println("학점: " + gpa);
}
public String getGrade() {
if (gpa >= 4.0) return "A";
else if (gpa >= 3.0) return "B";
else if (gpa >= 2.0) return "C";
else return "F";
}
public static void main(String[] args) {
Student student1 = new Student("홍길동", 20240001, 3.8);
Student student2 = new Student("김철수", 20240002, 4.2);
student1.printInfo();
System.out.println("등급: " + student1.getGrade());
System.out.println();
student2.printInfo();
System.out.println("등급: " + student2.getGrade());
}
}
예제 3: 은행 계좌
public class BankAccount {
private String accountNumber;
private String owner;
private double balance;
public BankAccount(String accountNumber, String owner) {
this.accountNumber = accountNumber;
this.owner = owner;
this.balance = 0.0;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println(amount + "원 입금 완료");
System.out.println("잔액: " + balance + "원");
} else {
System.out.println("입금액은 0보다 커야 합니다.");
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
System.out.println(amount + "원 출금 완료");
System.out.println("잔액: " + balance + "원");
} else {
System.out.println("출금 불가 (잔액 부족 또는 잘못된 금액)");
}
}
public void printInfo() {
System.out.println("=== 계좌 정보 ===");
System.out.println("계좌번호: " + accountNumber);
System.out.println("예금주: " + owner);
System.out.println("잔액: " + balance + "원");
}
public static void main(String[] args) {
BankAccount account = new BankAccount("123-456-789", "홍길동");
account.printInfo();
account.deposit(10000);
account.deposit(5000);
account.withdraw(3000);
account.withdraw(20000); // 잔액 부족
account.printInfo();
}
}
9. 자주 발생하는 문제
1. 클래스명과 파일명 불일치
문제:
// HelloWorld.java 파일
public class Hello { // 클래스명이 다름
public static void main(String[] args) {
System.out.println("Hello");
}
}
에러:
error: class Hello is public, should be declared in a file named Hello.java
해결: 파일명을 Hello.java로 변경하거나 클래스명을 HelloWorld로 변경
2. main 메서드 시그니처 오류
문제:
public class Test {
public void main(String[] args) { // static 누락
System.out.println("Test");
}
}
에러:
Error: Main method not found in class Test
해결: public static void main(String[] args) 정확히 작성
3. 세미콜론 누락
문제:
System.out.println("Hello") // 세미콜론 누락
에러:
error: ';' expected
해결: 모든 문장 끝에 ; 추가
4. 대소문자 구분
문제:
String name = "홍길동";
system.out.println(name); // System이 아닌 system
에러:
error: cannot find symbol
symbol: variable system
해결: Java는 대소문자를 구분합니다. System 정확히 작성
10. Java 컴파일과 실행 과정
컴파일 과정
1. 소스 코드 작성
HelloWorld.java
2. 컴파일 (javac)
javac HelloWorld.java
→ HelloWorld.class (바이트코드)
3. 실행 (java)
java HelloWorld
→ JVM이 바이트코드 해석 및 실행
4. 출력
Hello, Java!
JVM 동작 원리
HelloWorld.class (바이트코드)
↓
Class Loader (클래스 로딩)
↓
Bytecode Verifier (검증)
↓
JIT Compiler (Just-In-Time 컴파일)
↓
Native Code (기계어)
↓
실행
플랫폼 독립성:
Windows: HelloWorld.class → Windows JVM → 실행
macOS: HelloWorld.class → macOS JVM → 실행
Linux: HelloWorld.class → Linux JVM → 실행
동일한 .class 파일이 모든 플랫폼에서 실행!
11. 실전 팁
1. 코딩 컨벤션
// ✅ 좋은 코드
public class MyClass { // 클래스: PascalCase
private static final int MAX_SIZE = 100; // 상수: UPPER_SNAKE_CASE
private String userName; // 변수: camelCase
public void getUserName() { // 메서드: camelCase
return userName;
}
}
// ❌ 나쁜 코드
public class myclass { // 소문자
private int MaxSize = 100; // PascalCase
private String user_name; // snake_case
}
2. 주석
// 한 줄 주석
/*
* 여러 줄 주석
* 설명...
*/
/**
* JavaDoc 주석
* @param name 사용자 이름
* @return 인사 메시지
*/
public String greet(String name) {
return "안녕하세요, " + name + "님!";
}
3. 패키지
// com/example/myapp/Main.java
package com.example.myapp;
import java.util.Scanner;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// 코드...
}
}
4. 디버깅
public class Debug {
public static void main(String[] args) {
int a = 10;
int b = 0;
// 중단점 설정 (IDE에서)
int result = a / b; // ArithmeticException
System.out.println(result);
}
}
IntelliJ 디버깅:
- 중단점 설정: 줄 번호 왼쪽 클릭
- 디버그 실행:
Shift + F9 - 단계 실행:
F8(Step Over),F7(Step Into)
12. Java 버전
주요 버전 변화
| 버전 | 출시 | 주요 기능 |
|---|---|---|
| Java 8 | 2014 | Lambda, Stream API, Optional |
| Java 11 | 2018 | var, HTTP Client, String 메서드 |
| Java 17 | 2021 | Sealed Classes, Pattern Matching (LTS) |
| Java 21 | 2023 | Virtual Threads, Pattern Matching (LTS) |
LTS (Long-Term Support): 장기 지원 버전 (8, 11, 17, 21)
최신 기능 맛보기
// Java 10: var (타입 추론)
var name = "홍길동"; // String
var age = 25; // int
var list = new ArrayList<String>();
// Java 14: Switch Expression
String result = switch (day) {
case "월", "화", "수", "목", "금" -> "평일";
case "토", "일" -> "주말";
default -> "알 수 없음";
};
// Java 16: Record (불변 데이터 클래스)
record Person(String name, int age) {}
Person person = new Person("홍길동", 25);
System.out.println(person.name()); // 홍길동
정리
핵심 요약
- Java: 플랫폼 독립적, 객체지향 언어
- JDK: Java 개발 도구 키트 (컴파일러 포함)
- JVM: Java 가상 머신 (바이트코드 실행)
- 컴파일:
javac HelloWorld.java→.class - 실행:
java HelloWorld - 클래스: 모든 코드는 클래스 안에
- main 메서드: 프로그램 진입점
- 객체지향: 클래스와 객체로 프로그래밍
Java 기본 구조
// 패키지 선언 (선택)
package com.example;
// import 문 (선택)
import java.util.Scanner;
// 클래스 선언 (필수)
public class MyClass {
// 필드 (멤버 변수)
private int value;
// 생성자
public MyClass(int value) {
this.value = value;
}
// 메서드
public void printValue() {
System.out.println(value);
}
// main 메서드 (진입점)
public static void main(String[] args) {
MyClass obj = new MyClass(10);
obj.printValue();
}
}
실전 팁
- IDE 사용: IntelliJ IDEA 또는 Eclipse 권장
- 코딩 컨벤션: 클래스는 PascalCase, 변수/메서드는 camelCase
- 패키지 구조:
com.회사명.프로젝트명.기능 - 주석: JavaDoc 형식으로 문서화
- 예외 처리: try-catch로 에러 처리
- 디버깅: 중단점과 단계 실행 활용
- 버전 선택: LTS 버전 사용 (17 또는 21)
- 빌드 도구: Maven 또는 Gradle 사용
다음 단계
- Java 변수와 타입
- Java 클래스와 객체
- Java 컬렉션
관련 글
- C++ 초보자가 자주 하는 실수 Top 15 | 컴파일 에러부터 런타임 크래시까지
- HTML/CSS 시작하기 | 웹 개발 첫걸음
- Java 변수와 타입 | 기본 타입, 참조 타입, 형변환
- Java 클래스와 객체 | OOP, 상속, 인터페이스
- Java 컬렉션 | ArrayList, HashMap, Set