개요
이 문서는 Java의 객체 지향 프로그래밍에서 중요한 개념인 this, static, 코드 블록, 패키지 관리, 그리고 접근 제어자를 중심으로 설명합니다. 각 요소는 클래스 설계와 객체 동작을 이해하는 데 필수적이며, 실용적인 예제를 통해 명확히 살펴봅니다.
1. this 키워드
this는 현재 실행 중인 메서드를 소유한 객체를 가리키는 참조 변수입니다. 마치 문장 속 "나"가 화자를 지칭하듯, this는 현재 인스턴스를 의미합니다. 주로 생성자나 메서드 내에서 인스턴스 변수와 매개변수의 이름이 겹칠 때 구분하기 위해 사용됩니다.
public class Student {
private String name;
private int grade;
public Student(String name, int grade) {
this.name = name; // 인스턴스 변수에 매개변수 값 할당
this.grade = grade;
}
public void printInfo() {
System.out.println("학생 이름: " + this.name + ", 학년: " + this.grade);
}
}
위 예제에서 this.name은 인스턴스의 name 필드를, 단순 name은 매개변수를 의미합니다.
2. static 키워드
static은 클래스 수준에서 공유되는 멤버를 정의할 때 사용됩니다. 이 키워드로 선언된 변수나 메서드는 객체 생성 없이도 접근 가능하며, 모든 인스턴스가 동일한 데이터를 공유합니다. 마치 공용 게시판처럼, 한 곳에서 수정하면 전체에 반영됩니다.
public class Library {
public static int totalBooks = 0; // 모든 인스턴스가 공유
public static void addBook() {
totalBooks++;
}
public static void showTotal() {
System.out.println("총 도서 수: " + totalBooks);
}
}
// 사용 예
Library.addBook();
Library.addBook();
Library.showTotal(); // 출력: 총 도서 수: 2
주의사항: 정적 메서드는 인스턴스 변수나 인스턴스 메서드를 직접 호출할 수 없습니다. 왜냐하면 정적 메서드는 객체 없이 실행될 수 있으므로, 해당 인스턴스가 존재하지 않을 수 있기 때문입니다.
3. 코드 블록 종류
중괄호 {}로 묶인 코드 조각을 코드 블록이라 하며, 목적에 따라 여러 유형이 있습니다.
① 메서드 블록
메서드 내부에 정의되며, 메서드 호출 시마다 실행됩니다.
public void display() {
System.out.println("메서드 블록 실행");
}
② 동기화 블록
멀티스레드 환경에서 특정 코드 영역의 동시 접근을 방지합니다.
public void synchronizedTask() {
synchronized(this) {
System.out.println("동기화된 작업 수행");
}
}
③ 정적 초기화 블록
클래스가 처음 로드될 때 한 번만 실행되며, 정적 변수 초기화에 적합합니다.
static {
System.out.println("정적 블록: 클래스 로드 시 최초 1회 실행");
totalBooks = 100;
}
④ 인스턴스 초기화 블록
객체 생성 시마다 실행되며, 생성자 전에 공통 초기화 로직을 처리할 수 있습니다.
{
System.out.println("인스턴스 블록: 객체 생성 시 마다 실행");
}
4. 패키지 (Package)
패키지는 관련된 클래스들을 논리적으로 그룹화하고 네임스페이스를 관리하는 수단입니다.
패키지의 역할
- 클래스를 기능별로 체계화하여 관리
- 이름 충돌 방지 (예: com.company.util vs org.project.util)
- 접근 제어 지원 (default 접근 제한)
패키지 네이밍 규칙
역순 도메인 기반으로 작성: com.example.project.module
- 최상위: 조직 유형 (com, org, edu)
- 두 번째: 조직 이름 (google, huawei)
- 세 번째: 프로젝트명 (erp, blog)
- 네 번째: 모듈명 (dao, service, controller)
패키지 선언 및 사용
// 파일 상단에 선언
package com.example.app.user;
public class UserService {
// ...
}
import com.example.app.user.UserService;
public class MainApp {
public static void main(String[] args) {
UserService service = new UserService();
}
}
5. 접근 제어자 (Access Modifiers)
멤버(필드, 메서드, 생성자)의 접근 범위를 제한하여 캡슐화를 구현합니다.
| 제어자 | 같은 클래스 | 같은 패키지 | 다른 패키지의 자식 클래스 | 모든 곳 |
|---|---|---|---|---|
| private | ○ | × | × | × |
| default | ○ | ○ | × | × |
| protected | ○ | ○ | ○ | × |
| public | ○ | ○ | ○ | ○ |
예를 들어, 민감한 데이터는 private으로 감추고, getter/setter를 통해 안전하게 접근하도록 합니다.