Skip to content

260630_19_윤우상#95

Open
ssa25879 wants to merge 4 commits into
SurvivalCodingCampus:student/19_윤우상from
ssa25879:master
Open

260630_19_윤우상#95
ssa25879 wants to merge 4 commits into
SurvivalCodingCampus:student/19_윤우상from
ssa25879:master

Conversation

@ssa25879

Copy link
Copy Markdown

260630_19_윤우상

📝 과제 정보

  • 교육 주제: 인스턴스 기본조작

📋 체크리스트

  • 코드 컨벤션 준수 (Formatter 적용)
  • 모든 테스트 케이스 통과 (JUnit)

📷 실행 결과 (또는 테스트 결과)

NewBook

❓질문 및 어려웠던 점

  • 정렬 테스트를 위해 정렬된 값을 직접 작성할 때, publishDate(년, 월, 일)기준으로 정렬시키는데 같은 값은 입력된 순으로 정렬한다 라는 점을 생각하지 못해 예측하는 값 입력에 어려움을 느낌

🔄 자체 평가 & 회고

  • 기존에 Book.java 클래스가 이미 있어 과제 진행을 NewBook.java 로 새로 생성하여 진행
  • List.of() 를 사용하여 임시 리스트를 제작하여 assertEquals로 비교할 수 있다는 점을 알게됨.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

이번 변경에서는 인스턴스 기본 조작을 주제로 한 TIL을 추가하고, NewBook UML과 테스트 코드를 보강했습니다.
NewBookComparableCloneable을 구현하는 클래스로 정리되었고, title, publishDate, comment를 중심으로 생성자, 정렬 비교, 동등성 비교, 문자열 표현, 복제, getter/setter가 포함되었습니다.
또한 Asset, Book에도 toString(), equals(), hashCode()를 추가해 객체 비교와 출력 규칙을 일관되게 다듬었습니다.
테스트 측면에서는 NewBook의 equals, 정렬, 깊은 복사/얕은 복사를 검증하도록 JUnit 테스트가 추가되었고, StrongBoxTest의 메시지도 일부 조정되었습니다.

리뷰 관점에서는 다음을 다시 확인해 보면 좋겠습니다:

  • equals()hashCode()가 같은 기준을 사용하고 있는지
  • Comparable의 정렬 기준이 과제 요구와 정확히 맞는지
  • 복제(clone()) 시 참조 타입 필드가 의도대로 분리되는지
  • BookNewBook처럼 비슷한 역할의 클래스가 있을 때 책임이 잘 구분되는지

Walkthrough

AssetBook 클래스에 toString/equals/hashCode를 추가하고, Comparable<NewBook>Cloneable을 구현하는 NewBook 클래스를 신규 작성했다. NewBookpublishDate 연/월/일 기준 정렬, title+publishDate 기준 동등성, publishDate만 깊은 복제하는 clone()을 제공하며, JUnit 5 테스트로 검증된다. TIL 문서와 UML 다이어그램도 함께 추가되었다.

Changes

Object 메서드 구현 및 NewBook 클래스 추가

Layer / File(s) Summary
Asset, Book에 equals/hashCode/toString 추가
company/src/main/java/com/survivalcoding/Asset.java, company/src/main/java/com/survivalcoding/Book.java
Assetname 기준, BookisBn 기준으로 toString/equals/hashCode를 구현하고 java.util.Objects import를 추가한다.
NewBook 클래스 구현
company/src/main/java/com/survivalcoding/NewBook.java, company/NewBook.puml
title/publishDate/comment 필드와 두 생성자를 정의하고, publishDate 연·월·일 기준 compareTo, title+publishDate 기준 equals/hashCode, null 검증 setter, publishDate만 깊은 복제하는 clone()을 구현한다. UML 다이어그램도 추가된다.
NewBookTest 및 StrongBoxTest 수정
company/src/test/java/com/survivalcoding/NewBookTest.java, company/src/test/java/com/survivalcoding/StrongBoxTest.java
equals 동등성, Collections.sort 정렬 순서, 깊은/얕은 복사 동작을 JUnit 5로 검증한다. StrongBoxTestassertNull 실패 메시지에 key.name()을 추가한다.
TIL 문서
TIL/2026-06-30-Instance.md
Object 공통 메서드, equals/hashCode 동시 정의 원칙, Collections.sortComparator 활용법, 얕은/깊은 복사 차이를 정리한 학습 노트를 추가한다.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive PR 제목이 과제 번호와 이름만 담고 있어 변경 내용을 전혀 요약하지 못합니다. 예: 'NewBook 인스턴스 기본조작 구현'처럼 핵심 변경을 짧게 드러내는 제목으로 바꾸세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed 필수 섹션인 과제 정보, 체크리스트, 실행 결과, 질문, 회고가 모두 채워져 있어 템플릿을 대부분 충족합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ssa25879

ssa25879 commented Jun 30, 2026

Copy link
Copy Markdown
Author

다시 코드리뷰 시도해줘
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

@ssa25879 PR description image shows a UML-style class diagram for NewBook. NewBook implements Comparable and Cloneable, and has three fields: String title, Date publishDate, and String comment. It lists two constructors: NewBook(String title, Date publishDate, String comment) and NewBook(String title, Date publishDate, String). It also shows overridden methods compareTo(NewBook o), equals(Object o), hashCode(), toString(), and clone(), plus getters for all three fields and setters setTitle(String title), setPublishDate(Date publishDate), and setComment(String comment).

다시 코드리뷰 진행할게요.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
company/src/main/java/com/survivalcoding/NewBook.java (3)

33-39: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

주석 처리된 이전 구현 제거 권장.

개선 이유 메모와 함께 남겨둔 이전 정렬 로직 주석은 제거하는 편이 가독성에 좋습니다. (이력은 VCS에 남습니다.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/NewBook.java` around lines 33 - 39,
Remove the commented-out legacy sorting logic from NewBook; the old publishDate
comparison block and its improvement-note comment should be deleted from the
comparison-related code path, likely in the compareTo implementation, since the
VCS already preserves history. Keep the active sorting behavior unchanged and
leave only the current implementation in place.

41-49: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

compareToequals와 일관되지 않습니다.

equalstitle + 출간일(연/월/일)로 동등성을 판단하지만, compareTo는 출간일만 비교하고 title을 무시합니다. 따라서 출간일이 같고 제목이 다른 두 객체에 대해 compareTo0을 반환해, equals로는 다른 객체임에도 정렬상 동일하게 취급됩니다. TreeSet/TreeMap 등 비교 기반 컬렉션에서 한쪽이 누락되는 문제로 이어질 수 있으니, 출간일이 같을 때 title을 보조 비교 기준으로 추가하는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/NewBook.java` around lines 41 - 49,
`NewBook.compareTo` is inconsistent with `equals` because it compares only
publish date and ignores `title`, so two different books on the same date can
compare as equal. Update `compareTo` to keep the existing year/month/day
ordering in `NewBook` and, when those fields match, use `title` as a final
tiebreaker so the ordering aligns with `equals` and behaves correctly in
`TreeSet`/`TreeMap`.

16-16: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

publishDate에 대한 방어적 복사 고려.

Date는 가변 객체인데 생성자/세터로 받은 참조를 그대로 저장하고 getPublishDate()도 내부 참조를 반환합니다. 외부에서 Date를 변경하면 equals/hashCode가 바뀌어 컬렉션 내 무결성이 깨질 수 있습니다. 저장 및 반환 시 복사를 고려하세요.

Also applies to: 84-86, 99-104

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/NewBook.java` at line 16, `NewBook`의
`publishDate`는 가변 `Date`라서 생성자와 세터에서 받은 참조를 그대로 저장하고 `getPublishDate()`도 내부 참조를
노출하는 문제가 있습니다. `NewBook`, 관련 생성자/세터, `getPublishDate()`에서 저장할 때는 새 `Date`로 복사하고
반환할 때도 복사본을 반환하도록 수정해 외부 변경이 내부 상태에 영향을 주지 않게 하세요.
company/src/test/java/com/survivalcoding/NewBookTest.java (2)

16-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Deprecated Date 생성자 사용 및 연도 인자 의미 주의.

new Date(2026, 6, 30, ...)의 연도 인자는 1900 기준 오프셋이라 실제 연도는 3926이고 월은 0-기반(6=7월)입니다. 테스트 내부적으로는 일관되어 통과하지만 의도와 다른 값으로 읽힐 수 있습니다. Calendar/LocalDate 기반 생성으로의 전환을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/test/java/com/survivalcoding/NewBookTest.java` around lines 16 -
18, The test setup in NewBookTest uses deprecated Date constructors with
1900-based year and 0-based month semantics, so the created dates are
misleading. Replace the direct Date(...) calls with Calendar or java.time-based
creation in the test, and update the testDate, anotherTime, and anotherDate
setup to use explicit year/month/day values through clearly named date/time
APIs.

68-81: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

깊은 복사 테스트가 의도한 동작을 검증하지 못합니다.

clone()의 깊은 복사 대상은 가변 객체인 publishDate인데, 이 테스트는 불변 객체 String comment만 변경/비교합니다. comment는 String 재할당이라 얕은 복사여도 결과가 동일하므로 깊은 복사를 실제로 검증하지 않습니다. 원본의 publishDate(예: setMonth/setDate)를 변경한 뒤 clone의 publishDate가 영향받지 않음을 확인하도록 보강하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/test/java/com/survivalcoding/NewBookTest.java` around lines 68 -
81, The deep copy test in NewBookTest is checking the wrong field, since comment
is a String and does not verify clone behavior. Update testDeepCopy() to mutate
the mutable publishDate on book1 after book2 = book1.clone(), then assert that
book2.getPublishDate() is unaffected; use the existing clone(),
getPublishDate(), and date mutation methods (such as setMonth or setDate) to
confirm the deep copy.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@company/NewBook.puml`:
- Line 10: The NewBook constructor signature shown in the diagram is
inconsistent with the actual overloaded constructor. Update the NewBook element
in the diagram so the constructor reference matches the real signature
NewBook(String title, Date publishDate) and remove the extra trailing String
from the second constructor entry. Use the NewBook constructor labels in the
.puml content to locate and correct the mismatch.

In `@company/src/main/java/com/survivalcoding/Asset.java`:
- Around line 36-38: `Asset.hashCode()` is currently based on the mutable `name`
field, which can break `HashSet`/`HashMap` lookups after `setName()` changes it.
Update `Asset` so the hash/equality identity does not depend on a mutable
property: either make `name` immutable by removing its setter or switch
`equals()`/`hashCode()` to use only stable, immutable fields. Keep the
implementation of `hashCode()` and the corresponding `equals()` consistent.
- Around line 30-38: `Asset.equals()` and `Asset.hashCode()` currently use
`name` for all subclasses, but `Book` uses `isBn`, which can break symmetry
across the inheritance hierarchy. Update the equality strategy in `Asset` so it
matches the rest of the hierarchy: either restrict `Asset.equals()` with
`getClass()`/same-type checks, or align `Book` and other subclasses to the same
identity field. Keep the change localized around `equals()`/`hashCode()` in
`Asset` and the subclass equality methods so the comparison rules are
consistent.

In `@company/src/main/java/com/survivalcoding/NewBook.java`:
- Around line 92-97: The setTitle method in NewBook currently calls
title.isEmpty() before checking for null, which can throw a NullPointerException
instead of the intended IllegalArgumentException. Update setTitle to validate
that title is not null first, then check for emptiness, and keep the existing
exception/message behavior for invalid input so external calls through the
constructor are safely handled.
- Around line 41-49: The date handling in NewBook should be normalized because
getYear(), getMonth(), and getDate() on Date return unadjusted values, which can
lead to inconsistent compareTo, equals, hashCode, and toString behavior. Update
the NewBook date logic to use a LocalDate-based representation throughout, or
otherwise apply the proper year/month/day adjustments consistently in the
comparison and output methods so all date-related methods agree.

In `@TIL/2026-06-30-Instance.md`:
- Around line 59-63: The Comparator method name is incorrect in the
documentation, which mixes up Comparator and Comparable. Update the explanation
in the `Instance` markdown so it refers to `compare(a, b)` for Comparator
instead of `compareTo(a, b)`, and keep the behavior description aligned with the
`compare` contract while avoiding any reference to the single-argument
`compareTo` method.

---

Nitpick comments:
In `@company/src/main/java/com/survivalcoding/NewBook.java`:
- Around line 33-39: Remove the commented-out legacy sorting logic from NewBook;
the old publishDate comparison block and its improvement-note comment should be
deleted from the comparison-related code path, likely in the compareTo
implementation, since the VCS already preserves history. Keep the active sorting
behavior unchanged and leave only the current implementation in place.
- Around line 41-49: `NewBook.compareTo` is inconsistent with `equals` because
it compares only publish date and ignores `title`, so two different books on the
same date can compare as equal. Update `compareTo` to keep the existing
year/month/day ordering in `NewBook` and, when those fields match, use `title`
as a final tiebreaker so the ordering aligns with `equals` and behaves correctly
in `TreeSet`/`TreeMap`.
- Line 16: `NewBook`의 `publishDate`는 가변 `Date`라서 생성자와 세터에서 받은 참조를 그대로 저장하고
`getPublishDate()`도 내부 참조를 노출하는 문제가 있습니다. `NewBook`, 관련 생성자/세터,
`getPublishDate()`에서 저장할 때는 새 `Date`로 복사하고 반환할 때도 복사본을 반환하도록 수정해 외부 변경이 내부 상태에
영향을 주지 않게 하세요.

In `@company/src/test/java/com/survivalcoding/NewBookTest.java`:
- Around line 16-18: The test setup in NewBookTest uses deprecated Date
constructors with 1900-based year and 0-based month semantics, so the created
dates are misleading. Replace the direct Date(...) calls with Calendar or
java.time-based creation in the test, and update the testDate, anotherTime, and
anotherDate setup to use explicit year/month/day values through clearly named
date/time APIs.
- Around line 68-81: The deep copy test in NewBookTest is checking the wrong
field, since comment is a String and does not verify clone behavior. Update
testDeepCopy() to mutate the mutable publishDate on book1 after book2 =
book1.clone(), then assert that book2.getPublishDate() is unaffected; use the
existing clone(), getPublishDate(), and date mutation methods (such as setMonth
or setDate) to confirm the deep copy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 33d39746-07a4-4355-afdc-ac0ea22a2799

📥 Commits

Reviewing files that changed from the base of the PR and between f4f1884 and e4bf9c7.

⛔ Files ignored due to path filters (1)
  • image/NewBook.png is excluded by !**/*.png
📒 Files selected for processing (7)
  • TIL/2026-06-30-Instance.md
  • company/NewBook.puml
  • company/src/main/java/com/survivalcoding/Asset.java
  • company/src/main/java/com/survivalcoding/Book.java
  • company/src/main/java/com/survivalcoding/NewBook.java
  • company/src/test/java/com/survivalcoding/NewBookTest.java
  • company/src/test/java/com/survivalcoding/StrongBoxTest.java

Comment thread company/NewBook.puml
- String comment
--
+ {Constructor} NewBook(String title, Date publishDate, String comment)
+ {Constructor} NewBook(String title, Date publishDate, String)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

두 번째 생성자의 마지막 인자 표기 누락.

실제 코드의 2-인자 생성자는 NewBook(String title, Date publishDate)인데, 다이어그램에는 String이 추가로 표기되어 있어 실제 시그니처와 불일치합니다. 코드와 일치하도록 수정하세요.

✏️ 제안 수정
-    + {Constructor} NewBook(String title, Date publishDate, String)
+    + {Constructor} NewBook(String title, Date publishDate)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
+ {Constructor} NewBook(String title, Date publishDate, String)
{Constructor} NewBook(String title, Date publishDate)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/NewBook.puml` at line 10, The NewBook constructor signature shown in
the diagram is inconsistent with the actual overloaded constructor. Update the
NewBook element in the diagram so the constructor reference matches the real
signature NewBook(String title, Date publishDate) and remove the extra trailing
String from the second constructor entry. Use the NewBook constructor labels in
the .puml content to locate and correct the mismatch.

Comment on lines +30 to +38
@Override
public boolean equals(Object o) {
if (!(o instanceof Asset asset)) return false;
return Objects.equals(name, asset.name);
}

@Override
public int hashCode() {
return Objects.hashCode(name);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

상속 계층의 equals()/hashCode() 기준을 하나로 맞춰야 합니다.

Asset은 모든 하위 타입을 name으로 비교하는데, 같은 PR의 BookisBn으로만 비교합니다. 지금 구조에서는 하위 타입끼리 비교할 때 호출 방향에 따라 결과가 달라져 equals() 대칭성이 깨질 수 있습니다. Asset 쪽을 getClass() 기반으로 제한하거나, 계층 전체에서 동일한 식별 기준을 쓰도록 정리하는 편이 안전합니다.

예시 수정안
     `@Override`
     public boolean equals(Object o) {
-        if (!(o instanceof Asset asset)) return false;
+        if (o == null || getClass() != o.getClass()) return false;
+        Asset asset = (Asset) o;
         return Objects.equals(name, asset.name);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public boolean equals(Object o) {
if (!(o instanceof Asset asset)) return false;
return Objects.equals(name, asset.name);
}
@Override
public int hashCode() {
return Objects.hashCode(name);
`@Override`
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Asset asset = (Asset) o;
return Objects.equals(name, asset.name);
}
`@Override`
public int hashCode() {
return Objects.hashCode(name);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/Asset.java` around lines 30 - 38,
`Asset.equals()` and `Asset.hashCode()` currently use `name` for all subclasses,
but `Book` uses `isBn`, which can break symmetry across the inheritance
hierarchy. Update the equality strategy in `Asset` so it matches the rest of the
hierarchy: either restrict `Asset.equals()` with `getClass()`/same-type checks,
or align `Book` and other subclasses to the same identity field. Keep the change
localized around `equals()`/`hashCode()` in `Asset` and the subclass equality
methods so the comparison rules are consistent.

Comment on lines +36 to +38
@Override
public int hashCode() {
return Objects.hashCode(name);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

가변 필드를 해시 기준으로 쓰면 해시 컬렉션에서 객체를 잃어버릴 수 있습니다.

현재 hashCode()name에 의존하는데, name은 공개 setter로 나중에 바뀔 수 있습니다. 이 상태로 HashSet/HashMap에 넣은 뒤 setName()이 호출되면 조회·삭제가 실패합니다. name을 식별자로 쓸 거라면 불변으로 만들고, 가변이어야 한다면 equals()/hashCode() 기준에서 빼는 쪽이 맞습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/Asset.java` around lines 36 - 38,
`Asset.hashCode()` is currently based on the mutable `name` field, which can
break `HashSet`/`HashMap` lookups after `setName()` changes it. Update `Asset`
so the hash/equality identity does not depend on a mutable property: either make
`name` immutable by removing its setter or switch `equals()`/`hashCode()` to use
only stable, immutable fields. Keep the implementation of `hashCode()` and the
corresponding `equals()` consistent.

Comment on lines +41 to +49
if (this.getPublishDate().getYear() != o.getPublishDate().getYear()) {
return o.getPublishDate().getYear() - this.getPublishDate().getYear();
} else if (o.getPublishDate().getMonth() != this.getPublishDate().getMonth()) {
return o.getPublishDate().getMonth() - this.getPublishDate().getMonth();
} else if (o.getPublishDate().getDate() != this.getPublishDate().getDate()) {
return o.getPublishDate().getDate() - this.getPublishDate().getDate();
}
return 0;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

java.util.Date getYear getMonth getDate deprecated alternative LocalDate

💡 Result:

The methods getYear, getMonth, and getDate in java.util.Date have been deprecated since JDK 1.1 [1][2]. They are considered poor API design due to internationalization issues, 0-based month numbering, 1900-based year offsets, and lack of thread safety [1][3][4][5]. The modern, recommended alternative is the java.time API, introduced in Java 8 [6]. Specifically, java.time.LocalDate should be used for date values that do not require time zone or time-of-day information [3][6]. To migrate from legacy java.util.Date to java.time.LocalDate, use one of the following approaches: 1. Using Instant (Recommended for Java 8+): Convert the legacy Date to an Instant, apply the system's default time zone, and extract the LocalDate [7][8][9]. LocalDate localDate = date.toInstant.atZone(ZoneId.systemDefault).toLocalDate; 2. Using LocalDate.ofInstant (Recommended for Java 9+): This is a more concise approach available in modern Java versions [7][10]. LocalDate localDate = LocalDate.ofInstant(date.toInstant, ZoneId.systemDefault); Avoid using java.util.Calendar as a direct replacement, as it shares many of the same design flaws as java.util.Date [3][4][11]. Always prefer the java.time package for new code [3][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the target file and nearby symbols first
ast-grep outline company/src/main/java/com/survivalcoding/NewBook.java --view expanded || true

echo '--- file lines ---'
cat -n company/src/main/java/com/survivalcoding/NewBook.java | sed -n '1,220p'

echo '--- search for Date accessor usage ---'
rg -n "getYear\\(|getMonth\\(|getDate\\(|toString\\(" company/src/main/java/com/survivalcoding/NewBook.java

Repository: SurvivalCodingCampus/polytech_java2

Length of output: 6542


Date 접근자 사용을 정리하세요. getYear()/getMonth()/getDate() 값이 보정되지 않아 toString()에 1900 기준 연도와 0-based 월이 그대로 출력됩니다. compareTo/equals/hashCode/toStringLocalDate 기준으로 통일하거나, 최소한 출력·비교 시 보정값을 적용하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/NewBook.java` around lines 41 - 49,
The date handling in NewBook should be normalized because getYear(), getMonth(),
and getDate() on Date return unadjusted values, which can lead to inconsistent
compareTo, equals, hashCode, and toString behavior. Update the NewBook date
logic to use a LocalDate-based representation throughout, or otherwise apply the
proper year/month/day adjustments consistently in the comparison and output
methods so all date-related methods agree.

Comment on lines +92 to +97
public void setTitle(String title) {
if (title.isEmpty()) {
throw new IllegalArgumentException("책 제목은 비어있을 수 없습니다.");
}
this.title = title;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

setTitle에서 titlenull이면 NPE가 발생합니다.

title.isEmpty()titlenull일 때 의도한 IllegalArgumentException이 아니라 NullPointerException을 던집니다. 생성자가 외부 입력을 그대로 전달하므로 null 검증을 먼저 수행하세요.

🛡️ 제안 수정
     public void setTitle(String title) {
-        if (title.isEmpty()) {
+        if (title == null || title.isEmpty()) {
             throw new IllegalArgumentException("책 제목은 비어있을 수 없습니다.");
         }
         this.title = title;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void setTitle(String title) {
if (title.isEmpty()) {
throw new IllegalArgumentException("책 제목은 비어있을 수 없습니다.");
}
this.title = title;
}
public void setTitle(String title) {
if (title == null || title.isEmpty()) {
throw new IllegalArgumentException("책 제목은 비어있을 수 없습니다.");
}
this.title = title;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@company/src/main/java/com/survivalcoding/NewBook.java` around lines 92 - 97,
The setTitle method in NewBook currently calls title.isEmpty() before checking
for null, which can throw a NullPointerException instead of the intended
IllegalArgumentException. Update setTitle to validate that title is not null
first, then check for emptiness, and keep the existing exception/message
behavior for invalid input so external calls through the constructor are safely
handled.

Comment on lines +59 to +63
- 규칙은 `comparaTo()` 의 규칙과 동일
- `compareTo(a, b)` 일 때
- a > b -> 양수 (+1)를 리턴
- a = b -> 0을 리턴
- a < b -> 음수 (-1)를 리턴

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Comparator의 메서드명 혼동: compareTo(a, b)compare(a, b)

Comparator 인터페이스의 추상 메서드는 compare(T o1, T o2)입니다. compareTo(T o)Comparable 인터페이스의 메서드이며 단일 인자입니다. 문서에서 compareTo(a, b)라고 쓰면 두 인터페이스를 혼동하게 됩니다.

- 규칙은 `comparaTo()` 의 규칙과 동일
-     - `compareTo(a, b)` 일 때
+ 규칙은 `compareTo()` 의 규칙과 동일
+     - `compare(a, b)` 일 때
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- 규칙은 `comparaTo()` 의 규칙과 동일
- `compareTo(a, b)` 일 때
- a > b -> 양수 (+1)를 리턴
- a = b -> 0을 리턴
- a < b -> 음수 (-1)를 리턴
- 규칙은 `comparaTo()` 의 규칙과 동일
- `compareTo(a, b)` 일 때
- a > b -> 양수 (+1)를 리턴
- a = b -> 0을 리턴
규칙은 `compareTo()` 의 규칙과 동일
- `compare(a, b)` 일 때
- a > b -> 양수 (+1)를 리턴
- a = b -> 0을 리턴
- a < b -> 음수 (-1)를 리턴
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TIL/2026-06-30-Instance.md` around lines 59 - 63, The Comparator method name
is incorrect in the documentation, which mixes up Comparator and Comparable.
Update the explanation in the `Instance` markdown so it refers to `compare(a,
b)` for Comparator instead of `compareTo(a, b)`, and keep the behavior
description aligned with the `compare` contract while avoiding any reference to
the single-argument `compareTo` method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant