공공부하자개발 · 영어 학습 노트
자바
중급객체지향과 코어 라이브러리0/9 완료
  • 01상속, 다형성, 오버라이딩
  • 02추상 클래스 vs 인터페이스
  • 03예외 처리
  • 04java.lang 심화
  • 05컬렉션 프레임워크 딥다이브
  • 06메서드 활용 패턴 (중급)
  • 07Object 메서드와 비교
  • 08java.time 실무 날짜 계산
  • 09HTTP 와 JSON 기초
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 중급 › 04 / 9

java.lang 심화

String, StringBuilder, Wrapper
섹션 7진행 0 / 9
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

5. 자주 하는 실수 (Tip)

❌ 실수 1: 문자열을 ==로 비교

java
String status = order.getStatus();   // DB에서 읽어 온 값
if (status == "PAID") { ship(order); }   // 절대 true가 안 됨

DB/네트워크/파일에서 읽은 문자열은 런타임에 생성된 객체이므로 리터럴과 참조가 다르다.

java
if ("PAID".equals(status)) { ship(order); }   // 리터럴을 앞에 두면 status가 null이어도 NPE 없음
// 또는 enum으로 상태를 표현하면 == 비교가 안전하고 오타도 컴파일러가 잡음

❌ 실수 2: split에 정규식 특수문자를 그대로 사용

java
"192.168.0.1".split(".")      // 결과: []  (.은 "모든 문자"이므로 전부 구분자)
"a|b|c".split("|")            // 결과: [a, |, b, |, c]  (|는 "또는")
java
"192.168.0.1".split("\\.")    // [192, 168, 0, 1]
"a|b|c".split("\\|")          // [a, b, c]
// 또는 정규식 아닌 분리: Pattern.quote(".")  /  Splitter(Guava)

❌ 실수 3: 반환값을 버리는 String 메서드 호출

java
String name = "  kim  ";
name.strip();                  // 아무 효과 없음
name.toUpperCase();            // 아무 효과 없음
System.out.println(name);      // 출력: "  kim  "

String은 불변이라 메서드가 원본을 바꾸지 않는다.

java
String name = "  kim  ".strip().toUpperCase();   // 출력: KIM

❌ 실수 4: 루프에서 += 로 문자열 누적

java
String csv = "";
for (Order o : orders) csv += o.id() + "," + o.amount() + "\n";   // 주문 10만 건이면 수 초~수십 초
java
StringBuilder sb = new StringBuilder();
for (Order o : orders) sb.append(o.id()).append(',').append(o.amount()).append('\n');
String csv = sb.toString();
// 또는
String csv = orders.stream().map(o -> o.id() + "," + o.amount()).collect(Collectors.joining("\n"));

❌ 실수 5: Wrapper 타입을 ==로 비교

java
Integer userId = 1000, ownerId = 1000;
if (userId == ownerId) { grantAccess(); }   // false — 캐시 범위 밖

테스트에서 id를 1, 2로 쓰면 통과하고 운영에서 id가 1000을 넘으면 실패하는 전형적인 "운영에서만 나는 버그".

java
if (userId.equals(ownerId)) { grantAccess(); }
// 또는 Objects.equals(userId, ownerId)  — null 안전

❌ 실수 6: 벤치마크에 currentTimeMillis 사용

java
long start = System.currentTimeMillis();
doWork();
long elapsed = System.currentTimeMillis() - start;   // NTP 시간 동기화로 음수가 나올 수도

currentTimeMillis는 벽시계라서 시스템 시각이 조정되면 뒤로 갈 수 있다.

java
long start = System.nanoTime();
doWork();
long elapsedMs = (System.nanoTime() - start) / 1_000_000;   // 단조 증가 보장
자주 하는 실수 (Tip)
  • ❌ 실수 1: 문자열을 ==로 비교
  • ❌ 실수 2: split에 정규식 특수문자를 그대로 사용
  • ❌ 실수 3: 반환값을 버리는 String 메서드 호출
  • ❌ 실수 4: 루프에서 += 로 문자열 누적
  • ❌ 실수 5: Wrapper 타입을 ==로 비교
  • ❌ 실수 6: 벤치마크에 currentTimeMillis 사용
이전 섹션4 응용 변형 예제5 / 7다음 섹션6 연습 문제