📂 목차
📚 본문
자바는 다음 특징을 가진다
- 플랫폼 독립성: “Write Once, Run Anywhere” - 한 번 작성하면 어디서든 실행
- 객체지향 프로그래밍: 코드 재사용성과 유지보수성이 뛰어남
- 자동 메모리 관리: 가비지 컬렉션으로 메모리 누수 방지
- 모던 자바: 최신 버전에서 다른 언어의 장점을 흡수
- 람다 표현식: 함수형 프로그래밍 지원 (Java 8+)
- Stream API: 데이터 처리를 선언적으로 작성 가능
- 병렬 프로그래밍: 멀티코어 CPU 효율적 활용
- 멀티 스레딩 지원
- JIT 컴파일러
등등의 장점들을 이용할 수 있다.
Java 준비
자바를 설치하기 위해 JVM, JRE, JDK 를 먼저 살펴보자.
- JVM: Java Virtual Machine 이며, 실제로 자바 프로그램이 실행되는 환경이다. 자바 바이트 코드(.class) 를 해석해서 운영체제에 맞게 실행하는 곳이다.
- JRE: Java Runtime Environment 의 약자이고, JVM + 자바 표준 라이브러리(거의 필수적인 기능들을 담는 모듈)를 담고 있고, 자바 프로그램을 실행할 수 있다.
- JDK: Java Development Kit 이라고 불리고, JRE + 개발도구 이다. 개발 도구라고 함은 javac, jdb, javadoc 등 개발에 필요한 다양한 기능들을 넣어놓았다.
Java 버전별 주요 기능 정리
JDK 8
가장 많이 사용되었던 버전, 람다 표현식 도입
람다 표현식: 함수형 프로그래밍 스타일 도입을 위해 람다라는 익명 함수 기능 도입
기존 방식
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
}
run.run();
람다 표현식
// 두 줄 이상의 코드가 되면 중괄호로
Runnable run = () -> System.out.println("Hello, World!");
run.run()
이를 통해 forEach 문의 가독성이 상승하고 함수형 프로그래밍이 가능해짐.
JDK 11
모듈 시스템 안정화, HTTP Client API
기존 방식
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpExample {
public static void main(String[] args) throws Exception {
// HttpClient 생성
HttpClient client = HttpClient.newHttpClient();
// GET 요청 builder 패턴으로 생성
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://jsonplaceholder.typicode.com/posts/1"))
.GET()
.build();
// 동기 요청 (send)
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// 결과 출력
System.out.println("Status code: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}
비동기 요청
// 불변 객체 request 를 보내는 주체 HttpClient 인스턴스를 생성함
HttpClient client = HttpClient.newHttpClient();
// "https://jsonplaceholder.typicode.com/posts/1" 에 요청하는 http 방식의 request 생성
HttpRequest request = HttpRequest.newBuilder()
// 인터넷 자원 URI 생성
.uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
// 인스턴스 생성
.build();
// 요청을 전송하는 client 가 Async(비동기) 방식으로 요청을 보냄, 응답바디를 String 으로 읽음
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
// 앞단계가 완료되면 HttpResponse::body() 메서드 호출
.thenApply(HttpResponse::body)
// 앞단계가 완료되면 body를 받아서 표준 출력에 찍음
.thenAccept(System.out::println)
// 스레드를 join시키고 블록해서 위 명령이 끝날 때까지 기다림
.join();
HttpClient
는 불변 객체로 재사용이 되며, 동기와 비동기 전부 지원이 가능해졌고,HTTP/2
지원 및 요청과 응답을BodyHandler
로 처리가 가능(String
,File
,InputStream
)해졌다
JDK 17
패턴 매칭, 텍스트 블록, 레코드 클래스
기존 방식
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String name() { return name; }
public int age() { return age; }
@Override
public String toString() {
return "Person[name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object o) { ... }
@Override
public int hashCode() { ... }
}
레코드 클래스
public record Person(String name, int age) {}
불변의 특징을 지니고 있고, 위와 동일한 코드를 제공한다. 자주 사용하는데 핵심 로직과는 관련이 없고 코드가 긴 보일러플레이트 코드들을 간략히 할 수 있다. 보통 record
는 DTO
를 만들 때 쓰인다.
JDK 21
가상 스레드, 패턴 매칭 강화
Java 환경변수 설정
자바를 설치하고 간혹 실행이 안되는 경우가 있을 수 있는데 Window
와 Mac
은 다음 환경 변수가 세팅이 되어있는지 확인해야 한다.
Windows
:: JAVA_HOME 확인
echo %JAVA_HOME%
:: Path에 JAVA_HOME/bin 포함 여부 확인
echo %PATH%
Mac / Linux
# JAVA_HOME 확인
echo $JAVA_HOME
# Path에 JAVA_HOME/bin 포함 여부 확인
echo $PATH
두 변수가 제대로 설정되어 있지 않다면, java.exe
가 위치한 폴더를 찾아서 환경변수로 세팅해주자.
Windows
:: 설치된 JDK 확인 (Program Files 폴더 확인)
dir "C:\Program Files\Java\"
:: 또는 64비트 시스템은 Program Files (x86) 도 확인
dir "C:\Program Files (x86)\Java\"
위 명령어를 통해 설치된 JDK 폴더를 확인할 수 있고, 예를 들어 C:\Program Files\Java\(jdk)
이 설치되어 있다면,
JAVA_HOME
환경변수를 해당 경로로 설정해주면 된다.
:: 환경변수 설정 예시 (명령 프롬프트)
setx JAVA_HOME "C:\Program Files\Java\(jdk)"
setx PATH "%JAVA_HOME%\bin;%PATH%"
Mac
# 설치된 JDK 확인
ls -al /Library/Java/JavaVirtualMachines/
위 명령어를 통해 깔려있는 JDK 버전을 확인할 수 있고, /Library/Java/JavaVirtualMachines/(jdk)/Content/Home
을 JAVA_HOME 으로 환경변수 세팅해주면 된다. 세팅해줄때는 ~/.zshrc
혹은 ~/.bashrc
를 편집하면 된다.
nano ~/.zshrc
# mac os 에서 /usr/libexec/java_home 이라는 JDK 경로를 찾을 수 있도록
# 제공되는 실행파일임 -v 를 통해 버전을 입력할 수 있다.
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH=$PATH:$JAVA_HOME/bin
source ~/.zshrc
위 JAVA_HOME
에서는 ls로 검색해서 찾았던 /Library/Java/JavaVirtualMachines/(jdk)/Content/Home
이 절대경로를 직접 입력해주어도 된다.
Java 컴파일 및 실행하기
Java는 컴파일러와 인터프리터 성격을 모두 가지고 코드를 실행한다.
첫 단계에서는 소스코드를 전체 컴파일하여 JVM이 읽을 수 있는 바이트코드(.class 파일)로 변환한다.
이후 JVM은 이 바이트코드를 읽어 실행하게 된다.
소스코드 → 바이트코드 → JVM 실행
바이트코드 실행 방식에는 두 가지가 있다:
- 인터프리터 방식: 바이트코드를 한 줄씩 읽어 실행
- JIT(Just-In-Time) 컴파일러 방식: 자주 실행되는 코드 블록을 감지하여 기계어로 변환 후 실행
JIT
덕분에 순수 인터프리터보다 속도가 훨씬 빠르며, 반복 실행되는 코드의 성능이 크게 향상된다. 이제 이를 수행해보자.
# byte 코드 생성
javac (컴파일 할 java 파일 이름).java
java (컴파일 할 java 파일 이름)
자바는 컴파일 + 인터프리터 방식을 통해 플랫폼에 독립적으로 동작할 수 있게 된다.
문서화를 위한 Java Docs
자바의 문법은 추후에 다루고 Java 코드를 상대방에게 알려주기 위한 주석을 달 때 어떻게 다는지 살펴본다.
/**
* 여기는 docs 주석 입니다.
*/
/** 로 시작하며 줄바꿈 Enter
를 치면 알아서 자동으로 넣어야할 것들과 설명을 쓸 수 있도록 폼을 IDE
에서 만들어준다.
만약 안만들어준다면 다음 참고를 보고 작성하면 되겠다. 주석을 달 때는 다음 물음에 답할 수 있어야 한다.
- Why, 코드를 왜 그렇게 작성했는지
- How, 비즈니스 로직이 복잡하다면 어떻게 동작하는지
주석을 다는 것을 보기 전에 태그를 먼저 보자.
Java Docs Tag
JavaDoc 태그는 주석 안에서만 의미가 있는 메타 정보이다. 메타 정보는 정보를 설명하는 정보라고 보면 되겠다.
이를 문서 생성 도구(Javadoc)가 읽어서 HTML 문서, PDF, 마크다운 등으로 변환할 때 의미를 지니게 되며
문서를 찾을 때 쉽게 찾을 수 있게 된다.
JavaDoc에서 자주 사용하는 태그와 용도를 한눈에 정리하고, 코드에서 어떻게 쓰이는지 예시를 포함했다.
태그 | 용도 / 기능 | 사용 위치 / 설명 |
---|---|---|
@author |
클래스/인터페이스 작성자 표시 | 클래스/인터페이스 상단 |
@version |
클래스/인터페이스 버전 정보 | 클래스/인터페이스 상단 |
@since |
기능이 추가된 Java/API 버전 | 클래스, 메서드 |
@see |
관련 클래스, 메서드, 문서를 참조 | 클래스, 메서드 |
@param |
메서드 매개변수 설명 | 메서드 주석, 매개변수 하나당 작성 |
@return |
메서드 반환값 설명 | 메서드 주석 (void는 사용 X) |
@throws / @exception |
메서드에서 발생 가능한 예외 설명 | 메서드 주석, 예외마다 작성 |
@deprecated |
더 이상 사용되지 않는 기능 표시 | 클래스, 메서드, 필드 |
@link |
다른 클래스/메서드 하이퍼링크 생성 | 설명 문장 내 |
@code |
코드 조각 강조 | 설명 문장 내 |
@literal |
HTML 태그를 그대로 표시 | 설명 문장 내 |
클래스/인터페이스
: @author, @version, @since, @see, @deprecated메서드
: @param, @return, @throws, @see, @deprecated문장 내 강조/링크
: @link, @code, @literal
베스트 프랙티스는 아니지만 클래스, 메서드 등등의 주석에서 다음 폼을 따르면 좋을거 같아서 써보았다.
Class 주석 달기
클래스를 선언하는 곳 바로 위에 Java docs 주석을 위치시키고 다음 내용을 표현하면 좋다.
/**
* 간단한 클래스/메서드 설명
*
* <p>상세 설명을 추가할 수 있음.
* 여러 줄로 작성 가능하며, HTML 태그 일부도 사용 가능</p>
*
* <pre>예시 코드도 넣을 수 있음.
* 여러 줄 작성 가능</pre>
*
* @author 작성자
* @version 버전
* @see 관련 클래스/메서드 (ex. String#equals, java.lang.reflect 등등)
*/
Method 주석 달기
함수 선언 바로 위에 주석을 달면 되고, 클래스와는 다르게
함수는 특히 오류를 내뱉을 수 있으므로 던져지는 오류가 어떤 형태인지도 알려준다.
만약 오류가 여러 개면 throws
태그를 여러개 작성한다.
/**
* 한 줄 요약
*
* <p>상세 설명 (여러 줄 가능)</p>
*
* @param param1 설명
* @param param2 설명
* @return 반환값 설명
* @throws 예외설명
*
* <pre>
* // 예시 코드
* ClassName obj = new ClassName();
* obj.method(param1, param2);
* </pre>
*/
필드나 변수에 대한 주석은 한-두 줄로 충분하다.
Marker 사용하기
주석이 너무 많으면 사람들은 회색 글들중에 특별히 참고해야 할 만한 내용을 놓칠 수 있다.
이때 쓰는 것이 Marker
인데, 해당 코드 바로 위 혹은 옆에 한 줄로 작성하여 IDE 에서 색상이나 강조로 다른 주석보다 더 잘보이게 되는 주석이다.
다음 마커들이 있다:
- TODO: 나중에 해야 할 일, 미완성 기능을 표시하는 용도이다.
- FIXME: 버그나 문제가 있는 코드를 표시하게 된다.
- XXX: 위험하거나 주의가 필요한 코드이다. 보안상에 문제가 있다면 사용할 수 있다.
- HACK: 임시 방편 코드의 의미를 가진다.
- NOTE: 참고용 설명이다.