Service 계층 assert 표준은 도달 불가 분기를 assert가 아니라 throw new AssertionError로 막기로 했고, 근거는 이 대비였다.

도달 불가 분기의 assert false 는 -ea 가 꺼지면 조용히 통과하고,
throw new AssertionError 는 -ea 와 무관하게 항상 멈춘다.

주장 — assert false는 -ea 여부로 동작이 갈린다

도달 불가 분기에 쓴 assert false 는 -ea 가 꺼지면 조용히 통과하고 켜지면 멈춘다.

근거 종류는 1(기술 사실)이다.


반증 조건 — 컴파일이 안 되거나 동작이 반대면 반증이다

  • refuted — 두 형태 중 하나가 컴파일되지 않거나, -ea를 껐는데 멈추거나, 켰는데 통과한다
  • supported — 두 형태 모두 컴파일되고 -ea 끄면 통과·켜면 멈춘다
  • inconclusive — 대조군(throw new AssertionError)이 -ea와 무관하게 멈추지 않는다

「컴파일되지 않는다」를 반증에 넣은 이유는 그 형태에서는 주장이 성립할 자리가 없기 때문이다. 위험이 있다고 말하려면 그 코드가 존재할 수 있어야 한다.


설계 — 같은 분기를 switch 문과 switch 표현식 두 형태로 만든다

// 형태 1 — switch 문
switch (kind) { case A: ...; break; default: assert false; }

// 형태 2 — switch 표현식
int v = switch (kind) { case A -> 1; default -> { assert false; } };

먼저 javac로 컴파일하고, 컴파일된 형태만 -ea-da로 두 번 실행한다. 대조군은 같은 자리에 throw new AssertionError()를 둔 두 형태다. JDK 21에서 프레임워크 없이 돌렸다.


결과 — switch 표현식은 컴파일 단계에서 막혔다

AssertExpression   컴파일 실패 (에러 1)
  error: switch rule completes without providing a value
    default -> { assert false; }
  (switch rules in switch expressions must either provide a value or throw)

AssertStatement    -ea → AssertionError (exit 1)   ·   -da → 통과, 0 반환
ThrowStatement     -ea → AssertionError            ·   -da → AssertionError
ThrowExpression    -ea → AssertionError            ·   -da → AssertionError

판정은 refuted다. 반증 조건의 첫 항목(둘 중 하나가 컴파일되지 않는다)에 걸렸다.


예상과 달랐던 점 — 주장이 뒤집힌 게 아니라 범위가 좁혀졌다

switch 문에서는 주장이 정확히 그대로 관측됐다. -ea를 켜면 멈추고 끄면 조용히 통과하며 0을 돌려준다. 표준이 경계한 위험이 그 형태에서는 실재한다.

switch 표현식에서는 그 위험이 생길 자리가 없다. assert false만 쓴 분기는 값을 돌려주지 않아 컴파일이 거부된다. 더 눈에 띄는 것은 진단 문구다.

switch rules in switch expressions must either provide a value or throw

컴파일러가 「값을 주거나 던져라」라고 말한다. 표준이 정한 답(throw new AssertionError())을 컴파일러가 이미 강제하고 있다는 뜻이다.


이 결과가 표준에 남기는 것 — 규칙은 살고 근거의 범위가 줄어든다

규칙(도달 불가 분기에는 AssertionError를 던진다)은 흔들리지 않는다. 오히려 표현식 쪽에서는 컴파일러가 같은 답을 강제한다. 바뀌어야 하는 것은 근거를 어디까지 일반화해 적었는가다. 지금 글은 형태를 가리지 않고 말한다.

규칙은 바로 고치지 않는다. 표준 글에 > 반증: 줄을 달고 kind: 모순 이슈에서 문장에 형태 조건을 붙일지 정한다.


정리

  • switch 문에서는 주장대로다. -ea 끄면 통과(0 반환), 켜면 AssertionError
  • switch 표현식에서는 assert false가 컴파일되지 않는다. 위험이 생길 자리가 없다
  • 컴파일러 진단이 「값을 주거나 던져라」라고 말한다. 표준의 답과 같다
  • 대조군은 두 형태 모두 -ea와 무관하게 멈췄다

자신만의 철학을 만들어가는 중입니다.
최상단으로 이동했습니다!
확대 이미지

댓글남기기