JShell 은 자바 코드를 미리 검증해보는 프로토타이핑을 위한 도구이기 때문에 처음 학습하면서 예제를 간단히 실습해보거나 다른 라이브러리를 실험해볼 때 유용하다.
GUI 가 존재하는 툴은 아니기 때문에 커맨드 라인(윈도우면 CMD 창)에서 실행해야한다.
JShell 의 쓰임새
JShell 은 한줄 씩 읽고(Read) 평가 후 (Evalution) 결과를 출력(Print) 하고 계속해서 다음 코드 입력을 대기(Loop)하기 때문에 REPL 이라고도 한다,
즉, 인터프리터 처럼 동작하기 때문에 익숙하지 않은 라이브러리를 실험하거나 간단한 코드의 동작을 파악할 때 유용하게 사용할 수 있다.
하지만 오라클 공식 문서에서도 언급하듯이 JShell 이 이클립스와 같은 IDE 를 완전히 대체할 수 있는 도구는 아니다.
오라클 공식 문서에서는 JShell 에서 코드의 동작 여부를 확인하고 IDE 에 붙여넣어서 프로그래밍하는것을 권유한다.
JShell 실행
JShell 은 JDK 9 이상 버전 부터 제공되기 때문에 JShell 을 실행하기 위해선 먼저 JDK 9 이상 버전이 설치되어 있어야한다.
그리고, 환경변수 path 에 /jdk설치디렉터리/bin 경로가 등록되어 있다면, 커맨드 입력 창(CMD)을 열어 다음과 같이 JShell 을 실행할 수 있다.
% jshell
| Welcome to JShell -- Version 15.0.2
| For an introduction type: /help intro
jshell>
(파악하기 쉽게 % 가 있는 줄은 사용자가 직접 입력한 명령어라고 가정한다)
JShell 을 실행할때 verbose 옵션을 주어서 verbose 모드로 실행할 수 있는데, 간단히 말해서 JShell 이 명령을 실행하고 결과를 출력할 때 좀 더 자세한 도움말을 주는 모드다.
verbose 모드로 실행할 땐 다음과 같이 실행한다.
% jshell -v
| Welcome to JShell -- Version 15.0.2
| For an introduction type: /help intro
jshell>
다음은 일반 모드로 실행했을 때의 실행결과와 verbose 모드로 실행했을 때의 실행결과를 비교한 모습이다.
1. 일반 모드 실행 시 (변수 선언)
% jshell
| Welcome to JShell -- Version 15.0.2
| For an introduction type: /help intro
jshell> int val = 0;
val == > 0 // 변수 val 을 0으로 초기화 했다는 의미
2. verbose 모드 실행 시 (변수 선언)
% jshell -v
| Welcome to JShell -- Version 15.0.2
| For an introduction type: /help intro
jshell> int val = 0;
val ==> 0
| created variable val : int
결과를 보면 일반 모드보다 verbose 모드가 더 친절하다는 걸 알 수 있다.
하지만, 명령의 갯수가 늘어나고 복잡한 코드가 입력될 경우 난잡해 보일 수 있으니 일반 모드를 사용하도록 하자.
JShell 종료
JShell 을 종료할 땐 다음과 같이 입력한다.
jshell> /exit
| Goodbye
스니펫
위에서 JShell 을 이용해 간단히 변수를 선언하는 방법을 배웠다.
이렇게 JShell 가 처리하는 하나의 명령을 스니펫이라고 한다.
기본적으로 자바는 문장의 끝에 세미콜론을 붙여줘야하지만 스니펫은 안붙여도 된다는 장점이 있다.
변수
JShell 에서 변수를 선언하고 사용할 수도 있지만 변수를 선언하지 않고 표현식만 입력하고 변수로 활용할 수 있다.
이때는 JShell 이 자동으로 생성하는 변수에 초기화되는데, 이때 JShell 이 자동으로 생성하는 변수를 가리켜 스크래치 변수라고 한다.
jshell> 1 + 2
$1 ==> 3 // 스크래치 변수
이 스크래치 변수는 이후 다른 스니펫에서 사용 가능하다.
jshell> Math.multiplyExact($1,$1)
$2 ==> 9
변수를 직접 선언해서 사용할 경우, 동일한 변수 선언 스니펫을 여러번 입력할 수 있는데 이때는 기존 변수의 값에 덮어쓰게 된다.
jshell> int val = 0
val ==> 0
jshell> int val = 2
val ==> 2
또한 변수의 타입도 변경이 가능하다.
jshell> int val = 0
val ==> 0
jshell> int val = 2
val ==> 2
jshell> String val
val ==> null
메소드
JShell 로 메소드 선언 및 호출 또한 가능하다.
jshell> int getRandomInt(){
...> Random random = new Random();
...> return random.nextInt();
...> }
| created method getRandomInt()
jshell> getRandomInt();
$2 ==> -699245597
변수와 마찬가지로 메소드 또한 중복해서 정의할 경우 기존 내용에 덮어씌여진다.
또한, 아직 정의되지 않은 메소드를 사용하는 코드를 작성할수도 있다.
단, 이 경우 해당 코드를 실행하기 위해선 아직 정의되지 않았던 메소드를 정의해야한다.
jshell> int getRandomUnsigendInt(){
...> Random random = new Random();
...> return toUnsigendInt(random.nextInt());
...> }
| created method getRandomUnsigendInt(), however, it cannot be invoked until method toUnsigendInt(int) is declared
// 아직 정의되지 않은 메소드를 정의하지 않았을 경우
jshell> getRandomUnsignedInt()
| Error:
| cannot find symbol
| symbol: method getRandomUnsignedInt()
| getRandomUnsignedInt()
| ^------------------^
// 아직 정의되지 않은 메소드를 정의
jshell> int toUnsigendInt(int value){
...> return Math.abs(value);
...> }
| created method toUnsigendInt(int)
jshell> getRandomUnsigendInt()
$5 ==> 433089761
이렇게 사전에 정의되지 않은 메소드를 사용하는 방식을 가리켜 "사전 참조" 라고 부른다.
편집 모드
JShell 에서는 메소드 뿐만 아니라 클래스, 인터페이스 등 자바에서 제공하는 모든 문법을 사용할 수 있다.
하지만, 이렇게 커맨드 입력 라인으로 코드를 작성하기에는 가독성 문제도 그렇고 추후 잘못된 내용을 편집하기 까다롭다는 단점이 있다.
이러한 단점을 해결하기 위해 외부 편집기를 제공한다.
외부 편집기를 사용하면 메모장 처럼 코드를 한눈에 파악할 수 있고 편집에도 용이하다.
또한 외부 편집기에서 작성한 스니펫을 실시간으로 커맨드 라인에 적용할 수도 있다.
외부 편집기를 실행하는 방법은 다음과 같다.
jshell> /edit
외부 편집기 실행 모습
여기서 코드를 수정 및 추가하고 Accept 버튼을 누르면 커맨드 라인에도 동시에 입력되고 실행되는 것을 볼 수 있다.
Exit 버튼을 누르면 외부 편집기를 종료하고 커맨드 입력 라인 모드로 돌아간다.
유용한 단축키
단축키
설명
Tab
자동완성 기능 - 클래스 및 메소드 명 자동완성 - 명령어에 사용할 경우 탭을 누를 때 마다 다른 설명출력
Shift + Tab -> V
값에 사용할 경우 값을 평가해 해당 값을 저장할 수 있는 변수 선언문으로 자동변환
Shift + Tab -> i
사용하려는 클래스가 포함된 패키지 목록 출력 - 번호 선택 후 엔터를 누르면 import 문이 자동으로 추가
Ctrl + R
검색 모드 실행
유용한 명령어
명령어
설명
/var
현재까지 선언된 변수 리스트 출력
/methods
현재까지 정의된 메소드 리스트 출력
/list
현재까지 입력된 스니펫 리스트 출력
지금까지 JShell 에 대해 간단히 알아봤는데, 사실 이 외에도 아주 다양한 기능을 제공하고 있다.