2025.03.08 - [Core Java/Chapter 4] - 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.1 객체(Object)와 객체 지향 프로그래밍
코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.1 객체(Object)와 객체 지향 프로그래밍
[객체 지향 프로그래밍 입문: 객체의 특징과 클래스 구분]객체 지향 프로그래밍(Object-oriented Programming, 이하 OOP) 개요객체 지향 프로그래밍(OOP)은 절차 지향적 프로그래밍 기법을 대체하는 새로운
choosla.tistory.com
[ 자바 표준 라이브러리 기초 : Date와 LocalDate 활용하기 ]
4.2 표준 라이브러리 클래스 사용하기(Using Predefined Classes)
자바에서는 미리 정의된 표준 라이브러리 클래스(Predefined Classes)를 제공하며, 이를 통해 개발자는 직접 구현하지 않아도 다양한 기능을 활용할 수 있다.
특히, Math 클래스와 같은 일부 클래스는 내부 구현을 전혀 알 필요 없이 사용할 수 있도록 캡슐화(Encapsulation)되어 있으며, 객체를 생성하지 않고(static) 함수적으로만 사용할 수 있도록 설계되어 있다.
이러한 클래스들은 초기화 없이 바로 사용 가능하며, 필요한 기능만을 제공하는 방식으로 캡슐화되어 있어 더욱 효율적으로 활용할 수 있다.
4.2.1 객체와 객체 변수
객체로 작업하기 위해서는 객체를 설계하고 초기 상태를 특정해야 한다.
자바에서는 생성자(Constructor)를 사용하여 클래스를 인스턴스화하며, 이는 객체를 생성하고 초기화하는 특별한 메서드이다.
객체 생성과 생성자의 역할
자바에서 객체를 생성하는 방법은 new 키워드를 사용하여 생성자를 호출하는 것이다.
생성자는 항상 클래스의 이름과 같으며, 객체를 초기화하는 역할을 한다.
Date 클래스 예제
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date today = new Date();
System.out.println(today);
}
}
출력 결과 (실행 시점에 따라 다름)
Sat Mar 09 12:34:56 KST 2025
이처럼 new Date();를 호출하면 새로운 Date 객체가 생성되며, 현재 날짜와 시간으로 초기화된다.
즉, 생성자는 객체를 생성하고 초기화하는 특별한 메서드이다.
객체 변수와 참조 변수의 차이
객체와 객체 변수를 이해할 때 중요한 점은 객체 변수는 객체를 포함하는 것이 아니라, 객체가 위치한 메모리 주소를 저장하는 변수라는 것이다.
Date startTime; // 아무런 객체도 참조하지 않음
startTime = new Date(); // 객체를 생성하고 참조
위 코드에서 startTime 변수는 Date 타입의 객체를 참조할 수 있는 변수지만, 객체를 생성하기 전까지는 어떠한 객체도 참조하지 않는다.new Date();를 호출하면 Heap 메모리에 새로운 객체가 생성되고, startTime은 그 객체를 참조하게 된다.
객체 변수와 null 참조
객체 변수는 특정한 객체를 참조하지 않을 수도 있다. 이때 객체 변수의 값은 null이 될 수 있으며, 이를 null 참조(null reference)라고 한다.
Date startTime = null;
객체 변수가 null인 상태에서 메서드를 호출하면 NullPointerException이 발생할 수 있으므로, 이를 방지하기 위해 null 체크가 필요하다.
if (startTime != null) {
System.out.println(startTime);
}
객체 참조의 공유
객체 변수는 객체의 참조를 저장하는 변수이므로, 두 개의 객체 변수가 같은 객체를 참조할 수 있다.
Date rightNow = new Date();
Date startTime = rightNow; // 두 변수가 같은 객체를 참조
이 경우, rightNow와 startTime은 동일한 객체를 가리킨다.
즉, startTime을 변경하면 rightNow에도 영향을 미치게 된다.
startTime.setTime(0);
System.out.println(rightNow); // rightNow도 변경된 값이 출력됨

객체와 객체 변수 사이의 차이점
객체와 객체 변수를 이해할 때 중요한 점은 객체 변수는 객체 자체가 아니라 객체의 참조를 저장한다는 것이다.
1. 객체 변수를 선언했을 때
Date startTime;
이 시점에서 startTime은 객체 변수가 선언되었을 뿐, 아직 객체를 참조하고 있지 않다.
2. 객체를 생성하여 참조를 할당했을 때
startTime = new Date();
이제 startTime은 새로운 Date 객체를 가리킨다.
3. 객체를 다른 변수에 할당했을 때
Date anotherTime = startTime;
이제 anotherTime과 startTime은 동일한 객체를 참조하게 된다.
메모리 구조에서의 객체 참조
자바에서 new 키워드를 사용하여 객체를 생성하면, Heap 메모리에 새로운 객체가 할당된다.
객체 변수는 이 객체를 직접 저장하는 것이 아니라 객체의 주소(reference)를 저장한다.
Date startTime = new Date();
위 코드가 실행되면 다음과 같은 과정이 이루어진다.
new Date();를 실행하면 Heap 메모리에 새로운Date객체가 생성된다.startTime변수는 생성된Date객체의 메모리 주소를 저장한다.
이러한 방식은 객체의 효율적인 관리 및 재사용을 가능하게 한다.
객체를 참조하는 두 가지 방법
객체 변수는 새로운 객체를 생성하여 참조할 수도 있지만, 기존에 존재하는 객체를 참조할 수도 있다.
1. 새로운 객체 생성
Date startTime = new Date();
2. 기존 객체를 참조
Date rightNow = new Date();
Date startTime = rightNow;
이 경우 rightNow와 startTime은 동일한 객체를 가리키며, 한쪽에서 변경이 발생하면 다른 쪽에도 영향을 미친다.
객체와 객체 변수의 차이점 요약
| 개념 | 설명 |
|---|---|
| 객체(Object) | 메모리에 생성된 실제 데이터(인스턴스) |
| 객체 변수(Object Variable) | 객체를 참조하는 변수(객체의 메모리 주소를 저장) |
| 객체 변수의 초기 상태 | null 값을 가질 수 있으며, 참조할 객체가 없을 경우 NullPointerException이 발생할 수 있음 |
| 객체 참조의 공유 | 여러 개의 객체 변수가 하나의 객체를 참조할 수 있음 |
4.2.2 LocalDate 클래스
앞서 다룬 Date 클래스는 표준 Java 라이브러리의 일부로, 특정한 시간 지점을 나타내는 데 사용된다. 하지만 Date 클래스는 1970년 1월 1일 00:00:00 UTC를 기준으로 시간 값을 저장하기 때문에, 일반적인 달력 표기법과 차이가 있다.
이러한 문제를 해결하기 위해 Java 8부터는 java.time 패키지에 LocalDate 클래스가 추가되었다.
Date클래스는 특정 시점을 시간 단위까지 포함하여 표현한다.LocalDate클래스는 연도, 월, 일을 일반적인 달력 표기법으로 다룬다.
LocalDate 객체 생성 방법
- 현재 날짜를 가져오기
LocalDate.now()메소드는 시스템의 현재 날짜를 가져온다. LocalDate today = LocalDate.now();- 특정 날짜를 직접 지정하기
LocalDate.of(year, month, day)를 사용하면 특정 날짜를 직접 설정할 수 있다. LocalDate newYearsEve = LocalDate.of(1999, 12, 31);- 객체를 변수에 저장하기생성된
LocalDate객체를 변수에 저장하여 여러 번 사용할 수 있다. LocalDate birthday = LocalDate.of(2000, 5, 20);
LocalDate에서 연, 월, 일 가져오기
생성된 LocalDate 객체에서 연도, 월, 일을 가져올 수 있다.
int year = newYearsEve.getYear(); // 1999
int month = newYearsEve.getMonthValue(); // 12
int day = newYearsEve.getDayOfMonth(); // 31
이러한 메소드들은 캡슐화된 인스턴스 필드에서 값을 가져오므로, LocalDate 클래스 내부의 구현 방식을 알 필요 없이 쉽게 사용할 수 있다.
캡슐화의 핵심
- 클래스 내부의 데이터 표현 방식이 변경되더라도, 제공하는 메소드(
getYear(),getMonthValue(),getDayOfMonth())는 동일하게 유지된다. - 사용자는 내부 구현을 알 필요 없이 제공된 메소드를 활용하면 된다.
4.2.3 변경자(Mutator)와 접근자(Accessor) 메소드
Java에서 제공하는 LocalDate 객체는 불변 객체(immutable object) 이다. 즉, 한 번 생성된 LocalDate 객체는 변경할 수 없다.
예를 들어, 특정 날짜에 1000일을 추가하는 코드를 작성해 보자.
LocalDate aThousandDaysLater = newYearsEve.plusDays(1000);
이 코드를 실행하면 newYearsEve 객체는 변경되지 않고, 새로운 LocalDate 객체가 생성된다.
이와 달리, Java의 초기 버전에서 사용되던 GregorianCalendar 클래스는 mutable(변경 가능한) 객체였다.
GregorianCalendar someDay = new GregorianCalendar(1999, 11, 31);
// GregorianCalendar는 0부터 월을 시작하기 때문에 11은 12월을 의미
GregorianCalendar의 add() 메소드는 기존 객체를 직접 변경하는 변경자(Mutator) 메소드이다.
someDay.add(Calendar.DAY_OF_MONTH, 1000);
위 코드에서는 기존 someDay 객체 자체가 변경된다.
반면, LocalDate.plusDays(1000) 메소드는 새로운 객체를 반환하는 접근자(Accessor) 메소드이다.
접근자(Accessor)와 변경자(Mutator)의 차이
- 접근자 메소드 (
getYear(),getMonthValue(),getDayOfMonth()): 객체를 수정하지 않고 데이터를 조회하는 역할을 한다. - 변경자 메소드 (
add()inGregorianCalendar): 객체의 상태를 직접 변경한다. LocalDate는 변경자를 제공하지 않고, 연산 후 새로운 객체를 반환하는 방식을 사용한다.
4.2.4 LocalDate를 활용한 달력 출력 예제
아래는 위에서 배운 LocalDate 클래스를 활용하여 이번 달의 달력을 프롬프트에서 출력하는 프로그램의 예제이다.
이 프로그램은 현재 날짜를 가져와서 이번 달의 시작일과 요일을 계산한 후, 달력을 출력하는 방식으로 작동한다.
달력 프로그램의 핵심 단계
- 현재 날짜를 가져온다.
LocalDate date = LocalDate.now();- 현재 달과 일을 저장한다.
int month = date.getMonthValue(); int today = date.getDayOfMonth();- 현재 날짜를 해당 달의 1일로 설정하고, 해당 날짜의 요일을 가져온다.
date = date.minusDays(today - 1); // 이번 달의 시작일로 설정 DayOfWeek weekday = date.getDayOfWeek(); int value = weekday.getValue(); // 1 = 월요일, ... , 7 = 일요일- 달력 출력 준비: 주의 첫 번째 줄을 맞추기 위해 공백을 출력한다.
System.out.println("Mon Tue Wed Thu Fri Sat Sun"); for (int i = 1; i < value; i++) System.out.print(" "); // 들여쓰기- 날짜를 반복하면서 출력한다.
while (date.getMonthValue() == month) { System.out.printf("%3d", date.getDayOfMonth()); if (date.getDayOfMonth() == today) System.out.print("*"); // 오늘 날짜 강조 표시 else System.out.print(" "); date = date.plusDays(1); if (date.getDayOfWeek().getValue() == 1) // 한 주가 끝나면 줄 바꿈 System.out.println(); }
풀 코드
import java.time.*;
public class CalendarTest {
public static void main(String[] args) {
LocalDate date = LocalDate.now();
int month = date.getMonthValue();
int today = date.getDayOfMonth();
date = date.minusDays(today - 1); // 이번 달의 시작일로 설정
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getValue(); // 1 = 월요일, ... , 7 = 일요일
System.out.println("Mon Tue Wed Thu Fri Sat Sun");
for (int i = 1; i < value; i++)
System.out.print(" "); // 첫 주의 시작 요일 맞춤
while (date.getMonthValue() == month) {
System.out.printf("%3d", date.getDayOfMonth());
if (date.getDayOfMonth() == today)
System.out.print("*"); // 오늘 날짜 표시
else
System.out.print(" ");
date = date.plusDays(1);
if (date.getDayOfWeek().getValue() == 1) // 새로운 주 시작 시 줄 바꿈
System.out.println();
}
if (date.getDayOfWeek().getValue() != 1) // 마지막 줄 개행 정리
System.out.println();
}
}
2025.03.08 - [Core Java/Chapter 4] - 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.3 자신만의 클래스 정의하기
코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.3 자신만의 클래스 정의하기
2025.03.08 - [Core Java/Chapter 4] - 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.2 표준 라이브러리 클래스 사용하기 4.2 표준 라이브러리 클래스 사용하기4.2 표준 라이브러리 클래스 사용하기(Using Predefined Cla
choosla.tistory.com
'Core Java > Chapter 4' 카테고리의 다른 글
| 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.6 객체 생성 (0) | 2025.03.08 |
|---|---|
| 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.5 메소드 매개변수 (0) | 2025.03.08 |
| 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.4 정적 필드와 메소드 (0) | 2025.03.08 |
| 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.3 자신만의 클래스 정의하기 (0) | 2025.03.08 |
| 코어자바(Core Java) 12판 Chapter 4 리뷰 : 4.1 객체(Object)와 객체 지향 프로그래밍 (0) | 2025.03.08 |