목표
자바의 문법적 요소(Class, Constructor, Static)가 왜 만들어졌는지 코드를 통해 역추적한다. 불편한 코드를 먼저 작성해보고, 이를 개선하는 과정에서 자연스럽게 객체지향의 필요성을 납득하는 것이 목표다.
1. 데이터가 따로 노는 문제 (Class의 필요성)
쇼핑몰에서 상품 정보를 관리하는 기능을 구현한다고 가정해보자. 클래스를 배우기 전에는 보통 데이터를 배열에 담아서 관리했다.
Before: 배열을 이용한 관리
public class ShopMain {
public static void main(String[] args) {
// 상품 이름과 가격을 각각 다른 배열에 저장
String[] productNames = {"Laptop", "Mouse", "Keyboard"};
int[] productPrices = {1000000, 5000, 30000};
// 특정 상품 정보를 출력하려면 인덱스를 정확히 맞춰야 함
System.out.println(productNames[0] + ": " + productPrices[0]);
}
}
문제점 분석
위 코드의 문제는 데이터의 응집도가 떨어진다는 것이다. productNames와 productPrices는 논리적으로 한 몸이어야 하지만, 코드상으로는 완전히 남남이다. 만약 개발자가 실수로 정렬을 잘못해서 인덱스가 어긋나면, "3만원짜리 노트북"이 탄생하는 치명적인 버그가 발생한다. 이것이 바로 데이터의 파편화다.
After: 클래스로 묶기
이 문제를 해결하려면 연관된 데이터를 하나의 틀로 묶어야 한다. 이것이 클래스(Class)다.
class Product {
String name;
int price;
}
// 이제는 인덱스를 맞출 필요 없이 객체 하나로 관리됨
Product p = new Product();
p.name = "Laptop";
p.price = 1000000;
2. 불완전한 객체의 생성 (Constructor의 필요성)
클래스를 도입해서 데이터는 묶었지만, 여전히 구멍이 있다. new Product()만 하고 값을 채워 넣는 것을 깜빡한다면 어떻게 될까?
Product p = new Product();
// 개발자가 실수로 가격 설정을 누락함
// p.price = 1000000;
System.out.println(p.price); // 결과: 0 (무료 상품??)
이런 실수를 막으려면 "이름과 가격 없이는 애초에 객체를 못 만들게" 막아야 한다. 이때 사용하는 것이 생성자(Constructor)다.
class Product {
public Product(String name, int price) {
this.name = name;
this.price = price;
}
}
// 이제 값을 안 넣으면 컴파일 에러가 발생해서 실수를 원천 봉쇄함
Product p = new Product("Laptop", 1000000);
3. Static을 남발하면 안 되는 이유
학습 초기에는 static을 붙이면 객체 생성 없이 편하게 쓸 수 있어서 여기저기 붙이는 경우가 있다. 하지만 이는 메모리 관리 측면에서 위험할 수 있다. 그 이유는 생명주기(Lifecycle)가 다르기 때문이다.
- 일반 객체 (Instance):
new로 생성되었다가, 더 이상 쓰이지 않으면 Garbage Collector(GC)가 알아서 메모리를 회수한다. - Static 변수: 프로그램이 시작될 때 메모리(Method Area)에 올라가고, 프로그램이 종료될 때까지 내려오지 않는다.
즉, static으로 선언된 데이터가 많을수록 프로그램이 실행되는 내내 메모리를 점유하게 된다. 따라서 main 메서드나 Math.random() 같은 공용 유틸리티가 아니라면, 데이터는 반드시 객체(Instance) 내에서 관리하는 것이 옳다.
📚 함께 보면 좋은 'Antigravity & VS Code & Java' 로드맵
객체지향과 절차지향에 대한 학습이 끝났다면, 객체지향에 대해 자세히 학습해보는 시간을 가져봅시다.
Next Step 객체지향이란? (원리 익히기)
[Java] 객체지향 설계와 메모리구조: 싱글턴, 빌더 패턴, 그리고 불변성
'Dev Study > Java' 카테고리의 다른 글
| [Java] 다형성과 추상 클래스: if문의 늪에서 탈출하기 (3) | 2026.01.21 |
|---|---|
| [Java] 책임은 누구에게 있는가: 상속과 super의 본질 (0) | 2026.01.21 |
| [Java] 객체지향 설계와 메모리 구조: 싱글턴, 빌더 패턴, 그리고 불변성 (0) | 2026.01.15 |
| [Java] 자바 배열 정리: 메모리 구조, 깊은 복사, 2차원 배열 (0) | 2026.01.09 |
| [Java] 변수, 연산자, 그리고 제어문 (0) | 2026.01.06 |