REPL은 Read-Evaluate-Print-Loop(읽기-평가-출력-반복)의 약자로, 대화형 방식으로 코드를 입력하고 즉시 결과를 확인할 수 있는 환경을 의미합니다. Java 9부터 도입된 JShell에서는 모든 문장(statement)이 고유한 상태(state)를 가지며, 이 상태는 스니펫(snippet)과 변수의 실행 결과를 나타냅니다.
스니펫의 상태는 코드를 평가하는 JShell 인스턴스의 eval() 메서드 반환 결과를 통해 확인할 수 있으며, Java 9에서는 다음과 같이 일곱 가지 서로 다른 상태가 정의되어 있습니다.
JShell 스니펫의 7가지 상태
- DROPPED: 스니펫이 비활성화된 상태입니다. 사용자가 명시적으로 삭제(drop)한 경우에 해당합니다.
- NONEXISTENT: 아직 존재하지 않기 때문에 스니펫이 비활성화된 상태입니다.
- OVERWRITTEN: 동일한 이름을 가진 새로운 스니펫으로 대체되어 비활성화된 상태입니다.
- RECOVERABLE_DEFINED: 선언 스니펫이며, 본문에 복구 가능한 미해결 참조(unresolved references)나 기타 문제가 포함되어 있는 상태입니다.
- RECOVERABLE_NOT_DEFINED: 복구 가능한 미해결 참조나 기타 문제가 있는 선언 스니펫으로, 아직 정의가 완전하지 않은 상태입니다.
- REJECTED: 초기 평가 시점에 컴파일에 실패했고, JShell 상태를 이후에 변경하더라도 유효해질 수 없어 비활성화된 상태입니다.
- VALID: 컴파일 및 실행에 문제가 없는 유효한(valid) 스니펫 상태입니다.
예제 코드
다음 예제에서는 JShell 인스턴스를 생성하고 여러 문장을 한 번에 평가한 뒤, 각 스니펫의 상태를 확인하여 Status.VALID인 경우 성공 메시지를 출력합니다.
import java.util.List;
import jdk.jshell.*;
import jdk.jshell.Snippet.Status;
public class JShellTest {
public static void main(String args[]) {
JShell shell = JShell.create();
List<SnippetEvent> events = shell.eval("int a, b, sum; " + "a = 12; b = 11; sum = a + b; " +
"System.out.println(sum);");
for(SnippetEvent event : events) {
Snippet snippet = event.snippet();
Snippet.Status snippetstatus = shell.status(snippet);
if(snippetstatus == Status.VALID) {
System.out.println("Successfully executed");
}
}
}
}실행 결과
Successfully executed Successfully executed Successfully executed
위 실행 결과에서 세 번의 "Successfully executed" 메시지가 출력된 것을 확인할 수 있습니다. 이는 변수 선언, 값 대입, 합계 계산 및 출력에 해당하는 각 스니펫이 모두 VALID 상태로 성공적으로 평가되었음을 의미합니다.