[Java] System 클래스

clean·2024년 1월 5일
0
post-thumbnail

System Class

System 클래스는 이름대로 시스템에 대한 정보를 확인할 수 있는 클래스이다. System 클래스에는 생성자가 없으며, 3개의 스태틱 변수가 선언되어 있다.

선언 및 리턴 타입변수명설명
static PrintStreamerr에러 및 오류를 출력할 때 사용
static InputStreamin입력값을 처리할 때 사용
static PrintStreamout출력값을 처리할 때 사용

따라서 출력과 관련된 메소드들은 System 클래스가 아닌 PrintStream 클래스에서 찾아야 한다. PrintStream, InputStream은 모두 java.io 패키지에 정의되어 있다.

System 클래스에서 제공하는 메소드

System 클래스는 다음의 역할을 하는 메소드들을 제공한다.

  • 시스템 속성(Property)값 관리
  • 시스템 환경(Environment)값 조회
  • GC 수행
  • JVM 종료
  • 현재 시간 조회
  • 기타 관리용 메소드들

여기서 GC 수행, JVM 종료와 관련된 메소드들은 실행하면 안된다.
기타 관리용 메소드들은 잘 사용되지 않으므로 나중에 필요시 정리해볼 것이다.

시스템 속성(Property)값 관리

리턴 타입메소드 이름 및 매개 변수설명
static StringclearProperty(String key)key에 지정된 시스템 속성을 제거한다.
static PropertiesgetProperties()현재 시스템 속성을 Properties 클래스 형태로 제공한다.
static StringgetProperty(String key)key에 지정된 문자열로 된 시스템 속성값(value)를 얻는다.
static StringgetProperty(String key, String def)key에 지정된 문자열로 된 시스템 속성값(value)를 얻고 만약 없으면 def에 지정된 값을 리턴한다.
static voidsetProperties(Properties props)Properties 타입으로 넘겨주는 매개 변수에 있는 값들을 시스템 속성에 넣는다.
static StringsetProperty(String key, String value)key에 지정된 시스템 속성의 값을 value로 대체한다.

Properties 클래스는 java.util 패키지에 속하며, Hashtable의 상속을 받은 클래스이다. 자바 프로그램을 실행하면 Properties 객체가 자동으로 생성되고 그 값은 같은 JVM 내에서는 꺼내서 사용할 수 있다. 아래 예시처럼 사용하면 자바의 버전을 확인할 수 있다. Properties는 추가와 변경이 가능하다.

System.out.println("java.version: " + System.getProperty("java.version"));

이렇게 사용하면 자바 버전을 출력할 수 있다.

시스템 환경(Environment) 값 조회

리턴 타입메소드 이름 및 매개 변수설명
static Map<String, String>getenv()현재 시스템 환경에 대한 Map 형태의 리턴값을 받는다.
static Stringgetenv(String name)지정한 name에 해당하는 값을 받는다.

env는 변경할 수 없고 읽기만 할 수 있다. 이 값들은 대부분 OS나 장비와 관련된 것들이다. 예를 들어 다음과 같이 env 값을 조회할 수 있다.

System.out.println("JAVA_HOME: " + System.getenv("JAVA_HOME"));

JAVA_HOME은 JDK가 설치되어 있는 경로를 말한다. java.exe나 java라는 명령어가 있는 위치가 아닌 자바의 가장 상위 디렉토리를 의미.

GC 수행

리턴 타입메소드 이름 및 매개 변수설명
static voidgc()가비지 컬렉터를 실행
static voidrunFinalization()GC 처리를 기다리는 모든 객체에 대하여 finalize() 메소드를 실행

위 메소드들은 사용하면 안된다. 자바는 메모리 관리를 JVM이 알아서 해주고 개발자가 직접하지 않기 때문이다. 이 메소드들은 JVM이 호출해야하는 타이밍에 알아서 호출하니, 절대 건들이지 말자.

JVM 종료

리턴 타입메소드 이름 및 매개 변수설명
static voidexit(int status)현재 수행중인 JVM을 멈춘다.

이 메소드도 절대 호출하면 안된다. 이 메소드에서 눈여겨 볼것은 파라미터로 넘어가는 int status이다. status = 0이라면 정상적인 종료를 의미하고 0이 아니라면 비정상적인 종료를 의미한다.

현재 시간 조회

리턴 타입메소드 이름 및 매개 변수설명
static longcurrentTimeMillis()현재 시간을 밀리초 단위로 리턴한다.
static longnanoTime()현재 시간을 나노초 단위로 리턴한다.

currentTimeMillis()는 현재 시간을 나타낼 때 매우 유용한 메소드인데, UTC라는 Universal time을 기준으로 1970년 1월 1일 00:00부터 현재까지의 밀리초 단위의 차이를 출력한다. (밀리초는 1/1000를 의미하므로 1000ms == 1s이다)

nanoTime()은 시간의 차이를 측정하는 용도의 메소드이다. (1ns == 1/1,000,000,000s)

정리:
currentTimeMillis(): 현재 시간을 알고 싶을 때 호출
nanoTime(): 메소드의 수행시간을 재고 싶을 때 호출

System.out

System 클래스에 선언되어 있는 스태틱 변수 out, err는 타입이 PrintStream으로 동일하다. out은 정상적인 출력을, err는 에러가 발생했을 때 출력을 할 때 쓰인다.

PrintStream에는 다음 메소드들이 정의되어 있다.

  • print()
  • println()
  • format()
  • printf()
  • write()

print()와 println()은 줄바꿈을 하지 않냐, 하냐의 차이이고, println()은 매개변수가 없는 메소드가 존재하기 때문에 단순히 줄바꿈만 하고 싶다면 'System.out.println();"이렇게 써주면 된다.

print()와 println() 모두 reference type, primitive type 변수를 파라미터로 받을 수 있다. print와 println은 byte, short 타입을 파라미터로 받는 버전은 구현돼있지 않은데, 어차피 그 둘을 넘기면 int를 처리하는 print(), println() 메소드로 넘겨지기 때문에 문제 없이 처리 가능하다.

null과 print(), println()

다음 코드를 실행해보면 어떻게 될까?

public class ImmutableClassTest {
    public static void main(String[] args) {
        printNull();
    }

    public static void printNull() {
        Object obj = null;
        System.out.println(obj);
        System.out.println(obj + " is object's value");
    }
    
}

null이 들어가 있는 변수는 그냥 null로 출력되는 것을 확인할 수 있다. 왜 그런걸까?

우선 첫번째 출력문이 "null"로 출력되는 이유는, 객체.toString()이 아닌, String.valueOf(객체)의 값이 출력되기 때문이다.
즉,

System.out.println(String.valueOf(null));

과 같은 것이다. null에다 toString을 호출하면 널포인트 exception이 발생한다. 참고로 객체의 값을 출력할 때, 객체.toString()으로 호출하는 것보다, String.valueOf(객체)를 호출해서 출력하는 것이 더 안전하다.

두 번째도 제대로 출력이 되는 이유는 obj를 StringBuilder 클래스 append() 메소드에 파라미터로 넘겨 출력을 했기 때문이다. 즉, 두번째 출력문은 사실 아래와 동일하다.

System.out.println(new StringBuilder().append(obj).append(" is object's value"));

format(), printf()

printf()는 C언어의 printf()처럼 형식 지정자를 이용하여 출력하는 방식이다.

public PrintWriter printf(String format, Object... args)
System.out.printf("출력 format", 출력할 내용);

PrintStream 내부의 format() 메소드를 printf()의 내부에서 호출하고 있다.

profile
블로그 이전하려고 합니다! 👉 https://onfonf.tistory.com 🍀

0개의 댓글