String status = order.getStatus(); // DB에서 읽어 온 값
if (status == "PAID") { ship(order); } // 절대 true가 안 됨DB/네트워크/파일에서 읽은 문자열은 런타임에 생성된 객체이므로 리터럴과 참조가 다르다.
if ("PAID".equals(status)) { ship(order); } // 리터럴을 앞에 두면 status가 null이어도 NPE 없음
// 또는 enum으로 상태를 표현하면 == 비교가 안전하고 오타도 컴파일러가 잡음"192.168.0.1".split(".") // 결과: [] (.은 "모든 문자"이므로 전부 구분자)
"a|b|c".split("|") // 결과: [a, |, b, |, c] (|는 "또는")"192.168.0.1".split("\\.") // [192, 168, 0, 1]
"a|b|c".split("\\|") // [a, b, c]
// 또는 정규식 아닌 분리: Pattern.quote(".") / Splitter(Guava)String name = " kim ";
name.strip(); // 아무 효과 없음
name.toUpperCase(); // 아무 효과 없음
System.out.println(name); // 출력: " kim "String은 불변이라 메서드가 원본을 바꾸지 않는다.
String name = " kim ".strip().toUpperCase(); // 출력: KIMString csv = "";
for (Order o : orders) csv += o.id() + "," + o.amount() + "\n"; // 주문 10만 건이면 수 초~수십 초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"));Integer userId = 1000, ownerId = 1000;
if (userId == ownerId) { grantAccess(); } // false — 캐시 범위 밖테스트에서 id를 1, 2로 쓰면 통과하고 운영에서 id가 1000을 넘으면 실패하는 전형적인 "운영에서만 나는 버그".
if (userId.equals(ownerId)) { grantAccess(); }
// 또는 Objects.equals(userId, ownerId) — null 안전long start = System.currentTimeMillis();
doWork();
long elapsed = System.currentTimeMillis() - start; // NTP 시간 동기화로 음수가 나올 수도currentTimeMillis는 벽시계라서 시스템 시각이 조정되면 뒤로 갈 수 있다.
long start = System.nanoTime();
doWork();
long elapsedMs = (System.nanoTime() - start) / 1_000_000; // 단조 증가 보장