Java 9는 대화형 REPL(Read-Evaluate-Print-Loop) 도구인 JShell을 새롭게 도입하여, 코드 조각을 실행하고 그 결과를 즉시 확인할 수 있도록 지원합니다. 여기서 스니펫(snippet)이란 표준 자바 문법을 따르는 하나의 명령으로, 단일 표현식, 문장(statement) 또는 선언(declaration)을 의미합니다.
이번 글에서는 JShell 도구를 사용할 때 반드시 숙지해야 할 주요 규칙들을 살펴보겠습니다.
JShell 사용 규칙
- 스니펫은 import 선언, 클래스 선언, 메서드 선언, 인터페이스 선언, 필드 선언, 문장, 기본(primary) 표현식 등이 될 수 있습니다.
- package 선언은 허용되지 않습니다. JShell의 코드는 모두 임시적인 transient JShell 패키지 하위에 배치됩니다.
- 접근 제한자인 public, protected, private과 제어자인 final, static은 최상위(top-level) 선언에서 허용되지 않습니다. 만약 이를 작성하면 경고 메시지와 함께 무시됩니다.
- default와 synchronized 제어자는 최상위 선언에서는 전혀 사용할 수 없습니다. 다만 중첩된(nested) 컨텍스트 내부에서는 허용됩니다.
- abstract 제어자는 오직 클래스에만 적용할 수 있습니다.
- 사용자 입력이 불완전한 경우(예: System.out까지만 입력하고 println 부분을 생략한 경우), JShell의 자동 완성 API가 추가 입력을 요청하는 프롬프트를 표시합니다.
- 입력이 완전한 상태에서 세미콜론(;)이 누락된 경우, JShell이 이를 자동으로 붙여줍니다.
예제 코드
아래 예제에서는 getter 메서드를 갖춘 Employee 클래스를 정의한 뒤, new 연산자를 사용해 인스턴스를 생성하는 과정을 보여줍니다.
jshell> class Employee {
...> private String firstName;
...> private String lastName;
...> private String designation;
...> public Employee(String firstName, String lastName, String designation) {
...> this.firstName = firstName;
...> this.lastName = lastName;
...> this.designation = designation;
...> }
...> public String getFirstName() {
...> return firstName;
...> }
...> public String getLastName() {
...> return lastName;
...> }
...> public String getDesignation() {
...> return designation;
...> }
...> public String toString() {
...> return "Name = " + firstName + ", " + lastName + " | " +
...> "designation = " + designation;
...> }
...> }
| created class Employee
jshell> Employee emp = new Employee("Sai", "Adithya", "Content Developer");
emp ==> Name = Sai, Adithya | designation = Content Developer
실행 결과를 보면 클래스가 성공적으로 생성되었으며, 객체를 생성하는 동시에 재정의된 toString() 메서드 덕분에 객체 정보가 바로 출력되는 것을 확인할 수 있습니다. 이처럼 JShell을 활용하면 별도의 컴파일 과정 없이 자바 코드를 빠르게 실험하고 학습할 수 있습니다.