<aside> 💡
System.in
의 의미System.in
은 자바에서 표준 입력 스트림을 나타냅니다. System
클래스는 Java의 표준 입출력 객체들을 제공합니다.System.in
은 InputStream 타입으로, 키보드나 다른 입력 장치로부터 데이터(텍스트)를 받을 수 있는 바이트 기반 입력 스트림입니다.System.in
을 Scanner
와 함께 사용하면, Scanner
가 바이트를 문자열로 변환해주는 기능을 통해 텍스트 기반 입력을 쉽게 읽어낼 수 있습니다.nextInt()
: 입력된 값을 int
로 읽습니다.nextDouble()
: 입력된 값을 double
로 읽습니다.nextFloat()
: 입력된 값을 float
로 읽습니다.nextLong()
: 입력된 값을 long
으로 읽습니다.nextBoolean()
: 입력된 값을 boolean
으로 읽습니다. "true" 또는 "false"로 해석할 수 있는 값을 입력받습니다.next()
: 공백(스페이스, 탭, 엔터 등)을 기준으로 다음 단어를 읽습니다. 한 줄이 아닌 단어 하나만 읽습니다.nextLine()
: 현재 줄 전체를 읽습니다. 개행 문자가 나올 때까지 모든 입력을 읽어들입니다.Scanner
는 파일에서 데이터를 읽는 용도로도 사용할 수 있습니다. 파일을 읽을 때도 next()
, nextInt()
등 일반적인 메서드를 그대로 사용할 수 있으며, 파일 끝을 체크하는 메서드도 제공합니다.
입력이 더 남아 있는지 여부를 확인하기 위한 메서드들로, 반복문을 사용할 때 유용합니다.
hasNext()
: 다음 입력이 존재하는지 확인합니다.hasNextInt()
: 다음 값이 int
로 변환 가능한지 확인합니다.hasNextDouble()
: 다음 값이 double
로 변환 가능한지 확인합니다.hasNextLine()
: 다음 줄이 있는지 확인합니다.Scanner는 말그대로 무언가 입력 받도록 변환해주는 클래스이고 System.in으로 입력 스트림을 받아야 한다는 것이 핵심이다.
</aside>
<aside> 💡
</aside>
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package camp.nextstep.edu.missionutils;
import java.util.Scanner;
public class Console {
private static Scanner scanner;
private Console() {
}
public static String readLine() {
return getInstance().nextLine();
}
public static void close() {
if (scanner != null) {
scanner.close();
scanner = null;
}
}
private static Scanner getInstance() {
if (scanner == null) {
scanner = new Scanner(System.in);
}
return scanner;
}
}
<aside>
콜솔이라는 객체는 Scanner를 getInstance를 통해서 싱글톤으로 관리하고 있다. 따라서 Console을 한번 만들고 나면 Console을 닫기 전까지는 같은 Scanner와 같은 입력 스트림을 사용하게 된다. 또 close()를 하면 문제인게 Scanner 같은 객체는 만들어도 그만이지만 System.in 이 생기는 것이 아니기 때문에 문제가 될수도 있다고 한다.
</aside>
<aside> 💡
</aside>
package racingcar.view;
import camp.nextstep.edu.missionutils.Console;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.util.List;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
class InputViewTest {
private InputView inputView = new InputView();
@AfterEach
void set() {
Console.close();;
}
@Test
@DisplayName("inputCarNames 테스트")
void inputCarNames() {
//given
String readLine = "Car1,Car2,Car3";
System.setIn(new ByteArrayInputStream(readLine.getBytes()));
//when
List<String> carNames = inputView.inputCarnames();
//then
assertThat(carNames)
.isEqualTo(List.of("Car1", "Car2", "Car3"));
}
@Test
@DisplayName("inputGameTokens 테스트")
void inputGameTokens() {
//given
String readLine = "5";
System.setIn(new ByteArrayInputStream(readLine.getBytes()));
//when
int gameTokens = inputView.inputGameTokens();
//then
assertThat(gameTokens)
.isEqualTo(5);
}
<aside>
다음 코드에서 보게 되면 Test는 현재 Console 이 없는 상태이다 System.In은 존재하고 있다.이에 따라서 System.setOn을 Console 생성 전에 바꿔주고 Console.readLine을 호출하면 자동차 리스트가 들어간Console이 생기게 된다. Console은 싱글톤이기 때문에 한번 주입된 System.in을 계속 사용할 것이다. 아래 테스트에도 같은 것을 사용하는 것이 문제다. 이에 따라서 Console을 없애버림으로써 다른 System.in을 주입할 수 있는 Console을 만들고자 했고. Console.close()를 하는 과정에서 내부의 인풋 스트림을 날려버렸기 때문에 다시 만들어 준것이다.
</aside>
<aside> 💡
InputStream
:
System.in
: 기본적으로 표준 입력(키보드)에서 입력을 받을 때 사용됩니다.ByteArrayInputStream
: 메모리에 저장된 바이트 배열로부터 입력을 받을 수 있습니다. 테스트 환경에서 주로 사용됩니다.FileInputStream
: 파일에서 바이트 데이터를 읽어올 때 사용됩니다.Reader
:
FileReader
: 파일에서 문자 데이터를 읽어올 때 사용됩니다.InputStreamReader
: 바이트 스트림을 문자 스트림으로 변환할 때 사용되며, 다양한 인코딩을 지원합니다.String
:
Scanner
는 String
객체를 직접 사용할 수 있는 오버로드된 생성자도 있습니다. 예를 들어, 특정 문자열을 스캔할 수 있습니다.다만! Console은 강제로 scanner에 System.in을 주입해버리기 때문에…
</aside>
<aside> 💡
System.in
은 자바에서 기본적으로 제공하는 표준 입력 스트림입니다. 기본적으로 콘솔에서 사용자 입력을 받기 위해 사용됩니다. 사용자가 키보드로 입력한 데이터를 읽는 역할을 합니다.System.in
은 프로그램이 시작될 때 자동으로 생성되며, 사용자가 입력을 제공하기 전까지는 실제로 어떤 데이터도 포함하고 있지 않습니다. 사용자가 입력한 내용을 실시간으로 읽어옵니다.System.in
을 통해 읽을 수 있게 됩니다.ByteArrayInputStream
은 메모리 내의 바이트 배열을 기반으로 입력을 처리하는 스트림입니다. 생성할 때 반드시 바이트 배열을 제공해야 하며, 이 배열의 내용을 읽는 데 사용됩니다.ByteArrayInputStream
을 생성합니다.ByteArrayInputStream
에 제공된 배열의 내용은 스트림이 생성될 때 고정되며, 이후에는 변경할 수 없습니다. 따라서 입력 데이터를 동적으로 변경할 수는 없습니다.System.in
은 사용자 입력을 실시간으로 받아오는 기본 입력 스트림이며, 자동으로 생성되고 지속적으로 사용됩니다.ByteArrayInputStream
은 사용자가 제공한 바이트 배열을 읽는 스트림으로, 생성할 때 반드시 데이터를 포함해야 합니다.이러한 차이로 인해 System.in
은 콘솔로부터 동적인 입력을 받을 수 있는 반면, ByteArrayInputStream
은 고정된 데이터를 다루는 데 유용합니다.
System.in 은 동적으로 입력을 계속 받을 수 있다.
</aside>