[C++ to Java] 1. System Class
System Class에 대해 알아보자. 2021-12-22

Hello World!

안녕하세요! JustKode 입니다. 오늘은 java.lang 패키지에 있는 System Class에 대해서 알아 보겠습니다. 일단 java.lang 패키지에 대해서 설명 드리자면, Java 프로그래밍에 사용 되는 가장 기본적인 Class들을 모아놓은 패키지로, import를 하지 않아도 사용 가능 합니다. System ClassJVM을 거쳐 운영체제의 일부 기능을 사용 할 수 있도록 도와주는 클래스입니다. 또한, System Class는 모든 메서드가 Static으로 이루어져 있는 클래스로, 객체 생성 없이 모든 메서드를 사용 할 수 있습니다.

일단 간단한 Hello World를 한 번 출력 해 볼까요? 이 또한, System Class를 이용 하여 출력 할 수 있습니다. System의 멤버변수 out을 이용해 PrintStream 객체를 받아, 출력을 할 수 있습니다. System.out.println()을 이용하여 한 줄 출력이 가능 합니다.

Main.java

public class Main {
    static public void main(String[] args) {
        System.out.println("Hello World!");
    }
}
Hello World!

System.out

먼저 System.out에 대해 알아 보겠습니다. System.out은 다음과 같이, java.io.PrintStream 입니다.

public class Main {
    static public void main(String[] args) {
        // .getClass().getName()을 통해 클래스 이름을 알 수 있습니다.
        System.out.println(System.out.getClass().getName());
    }
}
java.io.PrintStream

java.io.PrintStream... Stream.. 어디서 본 것 같다면, 정답입니다. 우리가 **C++**에서도 InputStream, OutputStream, FileStream을 다뤘 듯이, Java 또한, InputStream, PrintStream, FileInputStream, FileOutputStream 개념이 존재 합니다. **C++**의 cout 역할을 하는 것이 Java에서의 PrintStream 입니다.

그럼 PrintStream의 메서드들을 알아 볼까요?

  • public void print(Object obj): 파라미터로 들어간 값을 개행 없이 출력 합니다. 각 객체의 타입의 맞게 Overloading 되어 있습니다.
  • public void println(Object obj): 파라미터로 들어간 값을 개행과 함께 출력 합니다. 각 객체의 타입의 맞게 Overloading 되어 있습니다.
  • public void printf(Object format, Object... args): 첫 번째 파라미터로 들어간 포맷에 맞게, 다른 파라미터들을 포멧에 맞게 출력합니다.
  • public void format(Object format, Object... args): 첫 번째 파라미터로 들어간 포맷에 맞게, 다른 파라미터들을 포멧에 맞게 출력합니다. printf와 같습니다.
public class Main {
    static public void main(String[] args) {
        System.out.print("Hello World?");
        System.out.println("Hello World!");
        System.out.printf("I am %d Years old.%n", 24);
        System.out.format("My GPA is %.1f%n", 4.313);
    }
}
Hello World?Hello World!
I am 24 Years old.
My GPA is 4.3

System.in

System.injava.io.BufferedInputStream 객체를 가집니다. **C++**의 InputStream과 일치 합니다. 입력을 담당하는 객체입니다.

public class Main {
    static public void main(String[] args) {
        // .getClass().getName()을 통해 클래스 이름을 알 수 있습니다.
        System.out.println(System.in.getClass().getName());
    }
}
java.io.BufferedInputStream

그럼 우리는 System.in을 이용하여, 어떻게 데이터를 입력 받을 수 있을까요? 우리는 Scanner 객체를 이용하여 입력을 받을 수 있습니다. Scanner Class는 import java.util.*;을 이용하여 import 할 수 있습니다. 그 다음 new Scanner(System.in)을 이용하여, Scanner 객체를 할당 받습니다. Scanner의 생성자의 입력 파라미터로, InputStream 계열을 삽입 하면 됩니다.

만약, 사용자에게 정수 입력을 받고자 한다면, Scanner.nextline()을 이용, 사용자의 입력을 String으로 입력 받은 후, Integer.parseInt(string)을 이용하여, int로 변환 합니다. 실수 라면, Float.parseFloat(string)을 이용 하여 float으로 변환 하면 됩니다.

import java.util.*;

public class Main {
    static public void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("2021년 기준, 당신의 나이는..?: ");
        String input = scanner.nextLine();
        int age = Integer.parseInt(input);

        System.out.printf("당신의 나이는 %d살 이군요!%n", age);
        System.out.printf("그러면.. 당신은, %d년에 태어 났군요!", 2021 - age + 1);
    }
}
2021년 기준, 당신의 나이는..?: 24
당신의 나이는 24살 이군요!
그러면.. 당신은, 1998년에 태어 났군요!

try, catch 추가

try, catch를 추가하여, 오류에 대한 예외도 간단하게 추가 할 수 있겠죠? parseInt, parseFloat에 대한 에러는 NumberFormatException을 이용 하면 됩니다. 예외 처리에 관련 한 내용은 나중에 더 다뤄 볼게요!

import java.util.*;

public class Main {
    static public void main(String[] args) {
        try {
            Scanner scanner = new Scanner(System.in);

            System.out.print("2021년 기준, 당신의 나이는..?: ");
            String input = scanner.nextLine();
            int age = Integer.parseInt(input);

            System.out.printf("당신의 나이는 %d살 이군요!%n", age);
            System.out.printf("그러면.. 당신은, %d년에 태어 났군요!", 2021 - age + 1);
        } catch (NumberFormatException e) {
            System.out.println("입력이 올바르지 않습니다. 정수를 입력 해 주세요!");
        }
    }
}
2021년 기준, 당신의 나이는..?: asdf
입력이 올바르지 않습니다. 정수를 입력 해 주세요!

Scanner.next()

Scanner.next()를 이용하여 공백을 기준으로 입력을 받을 수 있습니다. Scanner.nextLine() 과 혼용 해서 사용 할 때, 엔터 또한 문자로 인식 하기 때문에, 사용에 주의 하여야 합니다.

import java.util.*;

public class Main {
    static public void main(String[] args) {
        try {
            Scanner scanner = new Scanner(System.in);

            System.out.print("당신의 이름은?: ");
            String name = scanner.nextLine();

            System.out.print("당신의 생년월일은? (띄어쓰기로 구분 해 주세요): ");
            int year = Integer.parseInt(scanner.next());
            int month = Integer.parseInt(scanner.next());
            int day = Integer.parseInt(scanner.next());

            System.out.printf("%s님의 생년월일은 %d년 %d월 %d일 이군요!%n", name, year, month, day);
        } catch (NumberFormatException e) {
            System.out.println("입력이 올바르지 않습니다. 정수를 입력 해 주세요!");
        }
    }
}
당신의 이름은?: 박민재
당신의 생년월일은? (띄어쓰기로 구분 해 주세요): 1998 7 15
박민재님의 생년월일은 1998년 7월 15일 이군요!

Scanner.next()를 호출 한 후, 개행을 했을 때, 그 후에 실행되는 Scanner.nextLine()이 동작을 하지 않는 경우가 있습니다. 이는 개행으로 인하여 발생 하는 것으로, Scanner.nextLine()으로 버퍼에 남아 있는 개행 문자를 제거 함으로 써 해결 가능 합니다.

import java.util.*;

public class Main {
    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(System.in);

            System.out.print("당신의 생년월일은? (띄어쓰기로 구분 해 주세요): ");
            int year = Integer.parseInt(scanner.next());
            int month = Integer.parseInt(scanner.next());
            int day = Integer.parseInt(scanner.next());

            System.out.print("당신의 이름은?: ");
            scanner.nextLine();  // 개행 문자제거 위함
            String name = scanner.nextLine();

            System.out.printf("%s님의 생년월일은 %d년 %d월 %d일 이군요!%n", name, year, month, day);
        } catch (NumberFormatException e) {
            System.out.println("입력이 올바르지 않습니다. 정수를 입력 해 주세요!");
        }
    }
}
당신의 생년월일은? (띄어쓰기로 구분 해 주세요): 1998 07 15
당신의 이름은?: 박민재
박민재님의 생년월일은 1998년 7월 15일 이군요!

Scanner.nextInt()

Scanner.nextInt()를 이용하여, Scanner.next()로 받은 값을 바로 int로 변환 시킬 수 있습니다. Scanner.nextLong()long에 대해서, Scanner.nextDouble()double에 대해서, Scanner.nextFloat()float에 대해서 변환 합니다.

import java.util.*;

public class Main {
    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(System.in);
            
            System.out.print("당신의 이름은?: ");
            String name = scanner.nextLine();

            System.out.print("당신의 생년월일은? (띄어쓰기로 구분 해 주세요): ");
            int year = scanner.nextInt();
            int month = scanner.nextInt();
            int day = scanner.nextInt();

            System.out.printf("%s님의 생년월일은 %d년 %d월 %d일 이군요!%n", name, year, month, day);
        } catch (NumberFormatException e) {
            System.out.println("입력이 올바르지 않습니다. 정수를 입력 해 주세요!");
        }
    }
}
당신의 이름은?: 박민재
당신의 생년월일은? (띄어쓰기로 구분 해 주세요): 1998 7 15
박민재님의 생년월일은 1998년 7월 15일 이군요!

System Methods

다음은 System 객체 내부의 메서드에 대해서 알아 보겠습니다.

  • static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length): src 배열의 srcPos 부터 srcPos + length 까지의 요소들을 dest 배열의 destPos 부터 destPos + length 까지 대입 합니다.
public class Main {
    static public void main(String[] args) {
        int[] arr1 = {1, 2, 3, 4, 5};
        int[] arr2 = new int[5];

        System.arraycopy(arr1, 0, arr2, 0, 5);

        for (int i = 0; i < arr2.length; i++) {
            System.out.print(arr2[i] + ", ");
        }
        System.out.print('\n');
    }
}
1, 2, 3, 4, 5,
  • static long currentTimeMills(): 1970년 1월 1일 자정 부터의 지금 까지의 시간을 밀리초로 반환 합니다.
  • static void gc(): 가비지 컬렉션을 실행 합니다.
  • static Properties getPropertys(): 시스템 환경변수 테이블을 가져 옵니다.
  • static String getProperty(String key): 시스템 환경변수 테이블의 key에 해당하는 value를 반환 합니다.
  • static void setProperty(String key, String value): 시스템 환경변수 테이블의 keyvalue를 할당 합니다.
  • static void exit(int status): status 값을 반환하고, 프로그램을 종료 합니다.
import java.text.SimpleDateFormat;

public class Main {
    static public void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("현재 시각은: " + format.format(System.currentTimeMillis()));
        
        int[] arr = new int[10000];
        System.gc();

        System.out.println(System.getProperties());
        System.out.println("sun.jnu.encoding: " + System.getProperty("sun.jnu.encoding"));
        System.setProperty("Author", "JustKode");
        System.out.println("Author: " + System.getProperty("Author"));

        System.exit(1);
    }
}
현재 시각은: 2021-12-22 17:07:50
{Property Table 출력은 생략}
sun.jnu.encoding: UTF-8
Author: JustKode

Process finished with exit code 1

마치며

오늘은 System 클래스에 대해서 알아 보았습니다. 다음 시간에는 Java에서의 객체지향 프로그래밍에 대해서 알아 보도록 하겠습니다.