[Java 응용] java.lang 패키지 - 3. Wrapper, Class, System, Math 클래스

Kyung Jae, Cheong·2024년 8월 26일
0
post-thumbnail

0. Java.lang 패키지 개요

  • java.lang 패키지는 Java 프로그래밍 언어의 핵심 클래스를 포함하고 있는 패키지로, 자주 사용되는 기본 클래스들을 포함하고 있습니다.
    • 이 패키지는 자동으로 모든 Java 프로그램에 import되어 있으며, 별도의 import 구문 없이 사용할 수 있습니다.
  • java.lang 패키지의 대표적인 클래스들로는 Object, String, 래퍼 클래스들(Integer, Boolean, 등), Class, System 등이 있습니다.
  • lang 패키지에서 중요하게 다룰 수 있는 내용들이 상당히 많고 복잡하기 때문에 우선은 필요한 개념들을 하나씩 차례대로 정리해볼 예정입니다.
    1. Object 클래스
    2. String 클래스
    3. 래퍼 클래스들(Integer, Double, Boolean, 등)
    4. 그외 클래스들(Class, System, Math, 등)
  • 이번 포스트에서는 java.lang 패키지의 핵심 클래스 중 래퍼 클래스들(Integer, Double, Boolean, 등) & 그외 lang 패키지 클래스들(Class, System, Math, 등) 에 대해 자세히 살펴보겠습니다.

3. Wrapper 클래스

  • Java에서는 기본 데이터 타입(Primitive Types)과 참조형 데이터 타입(Reference Types)이 존재합니다.
    • 기본 데이터 타입은 메모리에서 직접 값을 저장하고 다루는 반면, 참조형 데이터 타입은 객체로 다뤄지며 다양한 메서드를 제공하여 유연한 작업을 할 수 있습니다.
  • 래퍼 클래스는 이러한 기본 데이터 타입을 객체로 다루기 위해 필요합니다. 기본 데이터 타입을 객체로 변환하면, 다음과 같은 이점들이 있습니다.
    • 컬렉션 클래스 사용 가능: ArrayList, HashMap 등 Java 컬렉션 프레임워크는 객체만을 다룹니다. 기본 데이터 타입을 사용하려면 래퍼 클래스로 변환해야 합니다.
      • 컬렉션은 추후에 자세히 다룰 예정
    • 유틸리티 메서드 사용 가능: 래퍼 클래스는 기본 데이터 타입을 다루는 다양한 유틸리티 메서드를 제공합니다.
      • 예를 들어, 문자열을 숫자로 변환하거나, 숫자의 최대값을 구하는 등의 작업이 가능합니다.
    • 객체 지향 프로그래밍: 객체 지향 패러다임에 따라 모든 데이터를 객체로 다룰 수 있으며, 이로 인해 더 일관된 코드 작성이 가능합니다.

3.1. 래퍼 클래스 종류

  • Java의 모든 기본 데이터 타입(int, double, boolean 등)은 대응되는 래퍼 클래스를 가지고 있으며, 이러한 클래스는 다양한 유틸리티 메서드를 제공합니다.
Wrapper Class대응 기본형 타입
Bytebyte
Shortshort
Integerint
Longlong
Floatfloat
Doubledouble
Characterchar
Booleanboolean
  • 참고로 이러한 래퍼클래스들은 불변객체이며, 값의 비교는 ==이 아닌 equals로 해주셔야합니다.

3.2. 래퍼 클래스의 주요 메서드

  • 래퍼 클래스들은 기본 데이터 타입을 다루는 유용한 메서드들을 제공합니다.

래퍼클래스 공통 주요 메서드

  • parse<Type>(String s): 문자열을 해당 기본 타입으로 변환 (Double.parseDouble, Boolean.parseBoolean 등).
  • valueOf(String s): 문자열을 해당 래퍼 클래스 객체로 변환.
    • 주로 String타입을 객체로 변환할때 많이 쓰입니다. (물론 다른 타입을 입력해도 됩니다)
  • <Type>Value(): 객체를 기본 타입으로 반환 (doubleValue(), booleanValue() 등).
  • compareTo(<Type> another): 두 래퍼 클래스 객체를 비교
    • 객체의 값이 비교대상(another)보다 더 크면 1, 같으면 0, 작으면 -1

래퍼클래스 메서드 예시 (Integer 클래스)

  • parseInt(String s): 문자열을 int로 변환합니다.
String numberStr = "123";
int num = Integer.parseInt(numberStr);
System.out.println(num); // 출력: 123
  • valueOf(String s): 문자열을 Integer 객체로 변환합니다.
Integer numObj = Integer.valueOf("123");
System.out.println(numObj); // 출력: 123
  • intValue(): Integer 객체를 기본 int 타입으로 반환합니다.
Integer numObj = Integer.valueOf(456);
int num = numObj.intValue();
System.out.println(num); // 출력: 456
  • compareTo(Integer another): 두 Integer 객체를 비교합니다.
Integer num1 = Integer.valueOf(100);
Integer num2 = Integer.valueOf(200);
int comparison = num1.compareTo(num2);
System.out.println(comparison); // 출력: -1 (100은 200보다 작음)

(참고) 래퍼클래스별 추가적인 메서드들

  • Byte, Short : toUnsignedInt()와 같은 바이트 단위의 추가적인 메서드들을 지원합니다. (거의 쓸일은 없습니다)
  • Integer,Long,Float,Double : sum(),max(),min()과 같은 간단한 연산을 수행하는 메서드들을 제공합니다.
  • Boolean : logicalAnd(),logicalOr(),logicalXor()과 같은 논리 연산을 수행하는 추가 메서드들을 제공합니다.

3.3. 래퍼 클래스의 오토박싱 & 오토언박싱

오토박싱(Auto-Boxing)

  • 오토박싱은 기본 데이터 타입이 자동으로 대응되는 래퍼 클래스로 변환되는 과정을 말합니다.
    • 쉽게 말해 int(기본) -> Integer(래퍼)
  • 이는 Java 5부터 도입되어, 개발자가 명시적으로 변환할 필요 없이 기본 타입과 래퍼 클래스를 혼용할 수 있게 했습니다.
int num = 10;
Integer integerObj = num; // 오토박싱: int -> Integer

오토언박싱(Auto-Unboxing)

  • 오토언박싱은 래퍼 클래스 객체가 자동으로 기본 데이터 타입으로 변환되는 과정을 말합니다.
    • 쉽게 말해 Integer(래퍼) -> int(기본)
  • 이 과정 또한 Java 5부터 지원됩니다.
Integer integerObj = Integer.valueOf(10);
int num = integerObj; // 오토언박싱: Integer -> int
  • 오토박싱과 오토언박싱 덕분에 기본 타입과 객체 타입을 자연스럽게 혼용할 수 있으며, 코드의 간결성과 가독성을 높여줍니다.

3.4. 래퍼클래스 vs 기본형변수

  • 상황에 따라 성능과 유연성 사이에서 적절히 선택하여 사용해야 합니다.

성능 차이

  • 메모리 사용: 기본 데이터 타입은 객체가 아니므로 메모리 사용량이 적고, 더 빠릅니다. 반면, 래퍼 클래스는 객체를 생성해야 하므로 추가적인 메모리와 연산이 필요합니다.
  • 성능: 래퍼 클래스는 추가적인 메모리 할당과 GC(가비지 컬렉션) 부담이 있을 수 있습니다. 기본 데이터 타입을 사용하는 것이 더 효율적이며, 특히 대량의 데이터를 처리할 때 성능 차이가 발생할 수 있습니다.

사용 시점 (언제 어떤걸 쓰나?)

  • 기본 데이터 타입 사용: 성능이 중요한 경우(예: 대규모 반복문, 성능에 민감한 연산 등) 기본 데이터 타입을 사용하는 것이 좋습니다. 기본 데이터 타입은 메모리 사용량이 적고, 속도가 빠릅니다.
  • 래퍼 클래스 사용: 기본 데이터 타입을 객체로 다뤄야 하는 경우(예: 컬렉션 프레임워크에서 사용하거나, 메서드에서 객체를 요구하는 경우) 래퍼 클래스를 사용해야 합니다. 또한, 문자열을 숫자로 변환하거나 특정 유틸리티 메서드를 사용해야 할 때도 래퍼 클래스가 필요합니다.

그럼 래퍼클래스를 왜 쓰나요?

  • 위 특징만 따지면 래퍼클래스의 장점이 거의 없는 것처럼 느껴질 수 있습니다만, 사실 래퍼클래스의 장점은 가독성을 높이고 유지보수를 쉽게 한다는 것에 있습니다.
  • 특히 요즘의 컴퓨터 연산 속도가 정말 많이 빨라졌고 대용량 메모리 가격도 상당이 싸졌기 때문에, 기본형 변수로 처리하는 것과 래퍼클래스로 처리하는 성능차이는 거의 없습니다.
    • 이러한 빠른 연산 속도에 비해서 네트워크 단위의 작업들이 훨씬 오래 걸리는 작업이라서 기본형 타입으로의 최적화를 진행할 의미가 더더욱 없습니다.
  • 따라서 유지보수 및 활용성(컬렉션 등등)을 따져보았을때, 왠만하면 기본형 클래스보다 래퍼클래스를 사용하는 것이 실무에선 더 권장되는 편입니다.
    • 물론 수만 ~ 수억개의 연산을 연속해서 수행하는 경우엔 기본형으로의 최적화 작업을 고려해보시는 것이 좋습니다. (물론 이런 경우도 많이 없긴 합니다...)

4. Class 클래스 (java.lang.Class)

  • java.langClass 클래스는 Java의 모든 클래스와 인터페이스의 메타데이터(즉, 클래스 정보를 표현하는 데이터)를 다루는 데 사용되는 핵심 클래스입니다.
  • 이 클래스는 Java Reflection API의 중요한 부분으로, 런타임에 클래스의 구조와 속성에 대해 탐색하고 조작할 수 있는 기능을 제공합니다.
    • Reflection도 상당히 다룰 내용이 많아서 여기선 Class 클래스에 대해서 간단하게만 다루고자합니다.

4.1. Class 클래스의 개요

  • Class 클래스는 java.lang 패키지에 포함되어 있으며, Java에서 모든 객체는 자신과 연결된 Class 객체를 가집니다.
  • Class 객체는 해당 클래스의 메타데이터를 포함하며, 클래스 이름, 부모 클래스, 구현된 인터페이스, 생성자, 필드, 메서드 등에 대한 정보를 제공할 수 있습니다.

Class 객체를 얻는 방법

  • Class 객체를 얻는 방법은 여러 가지가 있습니다
  1. .getClass() 메서드 사용: 특정 객체의 Class 객체를 얻는 방법.
String str = "Hello, World!";
Class<?> clazz = str.getClass();
  1. Class.forName() 메서드 사용: 클래스 이름을 문자열로 주어 Class 객체를 얻는 방법.
Class<?> clazz = Class.forName("java.lang.String");
  1. .class 리터럴 사용: 클래스의 리터럴로 Class 객체를 얻는 방법.
Class<String> clazz = String.class;
  1. 기본 타입의 TYPE 필드 사용: 기본 데이터 타입의 Class 객체를 얻는 방법.
Class<Integer> intClass = Integer.TYPE;
  • 참고로 class는 자바의 예약어라서 관행적으로 class 대신 변수명을 clazz로 사용합니다.

4.2 Class 클래스의 주요 메서드

  • Class 클래스는 클래스에 대한 다양한 정보를 얻을 수 있는 메서드를 제공합니다. 몇 가지 중요한 메서드를 살펴보겠습니다.

클래스 정보 조회

  • getName(): 클래스의 이름(패키지 포함 전체 이름)을 반환합니다.
  • getSimpleName(): 클래스의 간단한 이름(패키지 제외)을 반환합니다.
  • getSuperclass(): 부모 클래스의 Class 객체를 반환합니다.
  • getInterfaces(): 클래스가 구현한 인터페이스 목록을 반환합니다.
Class<?> clazz = String.class;
System.out.println(clazz.getName()); // 출력: java.lang.String

System.out.println(clazz.getSimpleName()); // 출력: String

Class<?> superClass = clazz.getSuperclass();
System.out.println(superClass.getName()); // 출력: java.lang.Object

Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> iface : interfaces) {
    System.out.println(iface.getName());
}
// 예시: 특정 클래스가 구현한 인터페이스 목록 출력

클래스 멤버 정보 조회

  • getFields(): 클래스의 모든 public 필드를 반환합니다.
  • getDeclaredFields(): 클래스의 모든 필드(접근 제한자 무관)를 반환합니다.
  • getMethods(): 클래스의 모든 public 메서드를 반환합니다.
  • getDeclaredMethods(): 클래스에 선언된 모든 메서드(접근 제한자 무관)를 반환합니다.
  • getConstructors(): 클래스의 public 생성자들을 반환합니다.
  • getDeclaredConstructors(): 클래스에 선언된 모든 생성자(접근 제한자 무관)를 반환합니다.

객체 생성 및 메서드 호출

  • newInstance(): 기본 생성자를 사용해 클래스의 새로운 인스턴스를 생성합니다.
    • Java 9 이후로 사용이 제한되어, Constructor.newInstance() 사용을 권장합니다.
  • getMethod(String name, Class<?>... parameterTypes): 클래스의 특정 메서드를 가져옵니다.
  • getConstructor(Class<?>... parameterTypes): 클래스의 특정 생성자를 가져옵니다.

기타 메서드

  • isInterface(): 클래스가 인터페이스인지 확인합니다.
  • isArray(): 클래스가 배열인지 확인합니다.
  • isPrimitive(): 클래스가 기본 데이터 타입인지 확인합니다.
boolean isInterface = clazz.isInterface();
System.out.println(isInterface); // false

boolean isArray = clazz.isArray();
System.out.println(isArray); // false

boolean isPrimitive = int.class.isPrimitive();
System.out.println(isPrimitive); // true

4.3. (참고) Class 클래스의 활용 예시

  • Class 클래스는 주로 Reflection API와 함께 사용되며, 런타임에 클래스의 정보를 얻고, 동적으로 객체를 생성하거나 메서드를 호출하는 데 활용됩니다. 아래는 간단한 활용 예시입니다.
public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // Class 객체 얻기
            Class<?> clazz = Class.forName("java.lang.String");

            // 클래스 정보 출력
            System.out.println("Class Name: " + clazz.getName());
            System.out.println("Superclass: " + clazz.getSuperclass().getName());

            // 필드 정보 출력
            Field[] fields = clazz.getDeclaredFields();
            System.out.println("Fields:");
            for (Field field : fields) {
                System.out.println(field.getName());
            }

            // 메서드 정보 출력
            Method[] methods = clazz.getDeclaredMethods();
            System.out.println("Methods:");
            for (Method method : methods) {
                System.out.println(method.getName());
            }

            // 생성자 사용해 인스턴스 생성
            Constructor<?> constructor = clazz.getConstructor(String.class);
            Object strObj = constructor.newInstance("Hello, Reflection!");
            System.out.println("Instance: " + strObj);

            // 메서드 호출
            Method method = clazz.getMethod("toUpperCase");
            String result = (String) method.invoke(strObj);
            System.out.println("Result of toUpperCase(): " + result);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. System 클래스

  • System 클래스는 Java에서 표준 입출력, 시스템 프로퍼티, 환경 변수, 메모리 관리 등과 관련된 다양한 유틸리티 메서드를 제공하는 클래스입니다.
    • System 클래스의 대부분의 메서드는 정적(static) 메서드로, 객체를 생성하지 않고도 사용할 수 있습니다.
  • 이 클래스는 java.lang 패키지에 포함되어 있으며, 자동으로 import되기 때문에 별도의 import 없이 사용할 수 있습니다.

5.1. System 클래스 주요 기능 및 메서드

표준 입출력(IO)

  • System 클래스는 표준 입력, 출력, 오류 스트림에 접근할 수 있는 정적 필드를 제공합니다.
    • System.out: 표준 출력 스트림으로, 콘솔에 데이터를 출력할 때 사용합니다.
    • System.err: 표준 오류 스트림으로, 오류 메시지를 콘솔에 출력할 때 사용합니다.
    • System.in: 표준 입력 스트림으로, 콘솔에서 데이터를 입력받을 때 사용합니다.
public class SystemIOExample {
    public static void main(String[] args) {
        System.out.println("This is standard output.");
        System.err.println("This is standard error.");
    }
}

시스템 프로퍼티(Property)

  • System 클래스는 시스템과 관련된 다양한 프로퍼티를 얻을 수 있는 메서드를 제공합니다.
  • 시스템 프로퍼티는 운영체제, 사용자 환경, Java 런타임 등과 관련된 정보를 포함합니다.
    • System.getProperty(String key): 지정한 키에 해당하는 시스템 프로퍼티 값을 반환합니다.
    • System.setProperty(String key, String value): 시스템 프로퍼티 값을 설정합니다.
  • 참고로 getProperty()만 사용하면 JSON 형식의 전체 프로퍼티를 얻을 수 있습니다.
public class SystemPropertyExample {
    public static void main(String[] args) {
        // 운영체제 이름 얻기
        String osName = System.getProperty("os.name");
        System.out.println("Operating System: " + osName);

        // 자바 버전 얻기
        String javaVersion = System.getProperty("java.version");
        System.out.println("Java Version: " + javaVersion);

        // 사용자 지정 시스템 프로퍼티 설정
        System.setProperty("my.custom.property", "CustomValue");
        System.out.println("Custom Property: " + System.getProperty("my.custom.property"));
    }
}

환경변수

  • Java 애플리케이션이 실행되는 환경에 따라 설정된 환경 변수들을 얻을 수 있습니다.
    • System.getenv(String name): 지정한 이름에 해당하는 환경 변수 값을 반환합니다.
    • System.getenv(): 모든 환경 변수를 포함하는 맵을 반환합니다. (JSON 형식)
public class SystemEnvExample {
    public static void main(String[] args) {
        // 특정 환경 변수 가져오기
        String path = System.getenv("PATH");
        System.out.println("PATH: " + path);

        // 모든 환경 변수 출력
        System.getenv().forEach((key, value) -> {
            System.out.println(key + ": " + value);
        });
    }
}

시간 관련 메서드

Java 애플리케이션의 실행 시간 측정, 성능 테스트 등에 유용한 시간 관련 메서드를 제공합니다.

  • System.currentTimeMillis(): 현재 시간을 밀리초 단위로 반환합니다. (UTC 1970년 1월 1일 00:00:00 기준)
    • 13자리의 Long 타입 Timestamp로 반환됩니다.
  • System.nanoTime(): 현재 시간을 나노초 단위로 반환합니다. (시스템의 시작 시간 기준 상대적인 시간)
public class SystemTimeExample {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();

        // 시간 지연 시뮬레이션
        try {
            Thread.sleep(2000); // 2초 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();
        System.out.println("Elapsed time: " + (endTime - startTime) + " milliseconds");

        // 나노초 단위 시간 측정
        long startNano = System.nanoTime();
        // 연산 또는 작업 수행
        long endNano = System.nanoTime();
        System.out.println("Elapsed time: " + (endNano - startNano) + " nanoseconds");
    }
}

메모리 관리

  • JVM의 메모리 상태를 확인하거나 가비지 컬렉션(Garbage Collection)을 강제 실행할 수 있습니다.
    • System.gc(): 가비지 컬렉터를 호출하여 사용하지 않는 메모리를 해제하도록 합니다.
    • System.exit(int status): 현재 Java 가상 머신을 종료합니다. 상태 코드를 통해 정상 종료 또는 비정상 종료를 나타낼 수 있습니다.
    • System.runFinalization(): 종료된 객체에 대해 최종화 작업을 실행합니다.
  • 참고로 실무에선 거의 쓰일 일이 없긴 합니다.
public class SystemMemoryExample {
    public static void main(String[] args) {
        System.out.println("Free memory before GC: " + Runtime.getRuntime().freeMemory());
        System.gc(); // 가비지 컬렉터 호출
        System.out.println("Free memory after GC: " + Runtime.getRuntime().freeMemory());

        // JVM 종료
        System.out.println("Exiting the program...");
        System.exit(0);
    }
}

6. Math 클래스 (+Random 클래스)

  • Java의 Math 클래스와 Random 클래스는 수학적 계산과 난수 생성에 사용되는 주요 유틸리티 클래스입니다.
    • 이 두 클래스는 수학 연산이나 난수 생성이 필요한 경우 자주 사용되며, 다양한 메서드를 통해 복잡한 작업을 쉽게 수행할 수 있도록 도와줍니다.
  • 참고로 Random Class는 java.lang이 아닌 java.util소속 메서드입니다. 하지만 Math 클래스의 random()메서드가 Random메서드를 이용하기 때문에 추가적으로 다루어 봅니다.

6.1. Math 클래스

  • Math 클래스는 Java에서 다양한 수학 연산을 수행하는 데 사용되는 유틸리티 클래스입니다.
    • 이 클래스는 정적 메서드와 상수들을 제공하며, 수학적 계산에 필요한 다양한 기능을 포함하고 있습니다.
    • 이 클래스의 모든 메서드는 정적(static) 메서드로, 객체를 생성하지 않고도 사용할 수 있습니다.

Math 클래스 주요 기능 및 메서드

상수 (Static Fields)

Math 클래스는 두 가지 중요한 수학적 상수를 제공하며, 이를 통해 다양한 수학 연산을 수행할 수 있습니다.

  • Math.PI: 원주율(π) 값으로, 약 3.141592653589793입니다.
  • Math.E: 자연상수(e) 값으로, 약 2.718281828459045입니다.
System.out.println("Math.PI = " + Math.PI); // 출력: Math.PI = 3.141592653589793
System.out.println("Math.E = " + Math.E);   // 출력: Math.E = 2.718281828459045

기본 연산 메서드

Math 클래스는 기본적인 수학 연산을 위한 여러 메서드를 제공합니다.

  • max(int a, int b): 두 값 중 더 큰 값을 반환합니다.
  • min(int a, int b): 두 값 중 더 작은 값을 반환합니다.
  • abs(int a): 주어진 값의 절대값을 반환합니다.
  • clamp(int value, int min, int max): 주어진 값을 지정된 범위 내로 제한합니다. (Java 21 도입)
System.out.println("max(10, 20) = " + Math.max(10, 20)); // 출력: 20
System.out.println("min(10, 20) = " + Math.min(10, 20)); // 출력: 10
System.out.println("abs(-10) = " + Math.abs(-10));       // 출력: 10
System.out.println("clamp(-10, 0, 100) = " + Math.clamp(-10, 0, 100)); // 출력: 0

지수 및 로그 연산 메서드

지수와 로그와 관련된 다양한 수학 연산을 수행할 수 있는 메서드들을 제공합니다.

  • pow(double a, double b): a의 b제곱 값을 반환합니다.
  • exp(double a): e^a 값을 반환합니다.
  • log(double a): 주어진 값의 자연 로그(ln)를 반환합니다.
  • log10(double a): 주어진 값의 상용 로그(log10)를 반환합니다.
  • sqrt(double a): 주어진 값의 제곱근을 반환합니다.
  • cbrt(double a): 주어진 값의 세제곱근을 반환합니다.
System.out.println("pow(2, 3) = " + Math.pow(2, 3));     // 출력: 8.0
System.out.println("exp(2) = " + Math.exp(2));          // 출력: 7.3890560989306495
System.out.println("log(10) = " + Math.log(10));        // 출력: 2.302585092994046
System.out.println("log10(10) = " + Math.log10(10));    // 출력: 1.0
System.out.println("sqrt(25) = " + Math.sqrt(25));      // 출력: 5.0
System.out.println("cbrt(27) = " + Math.cbrt(27));      // 출력: 3.0

반올림 및 정밀도 메서드

소수점 이하의 값을 반올림, 올림, 내림 등의 방식으로 처리하는 메서드를 제공합니다.

  • round(double a): 가장 가까운 정수로 반올림합니다.
  • ceil(double a): 주어진 값보다 크거나 같은 가장 작은 정수를 반환합니다.
  • floor(double a): 주어진 값보다 작거나 같은 가장 큰 정수를 반환합니다.
  • rint(double a): 가장 가까운 정수값을 반환합니다. 반올림 방식이 round()와 다를 수 있습니다.
System.out.println("round(3.14) = " + Math.round(3.14));        // 출력: 3
System.out.println("ceil(3.14) = " + Math.ceil(3.14));          // 출력: 4.0
System.out.println("floor(3.14) = " + Math.floor(3.14));        // 출력: 3.0
System.out.println("rint(3.14) = " + Math.rint(3.14));          // 출력: 3.0

// 소수점 이하 자리수 제한
System.out.println("round(3.141592 * 100) / 100.0 = " + Math.round(3.141592 * 100) / 100.0); // 출력: 3.14

// BigDecimal & RoundingMode 사용
BigDecimal bigDecimal = new BigDecimal("3.141592");
System.out.println("bigDecimal.setScale(2, RoundingMode.HALF_UP) = " + bigDecimal.setScale(2, RoundingMode.HALF_UP)); // 출력: 3.14
  • 참고로 보다 정밀한 숫자 연산 및 반올림이 필요한 경우엔 java.mathbigDecimalRoundingMode등을 사용하실 수 있습니다.

삼각함수 메서드

삼각함수와 관련된 다양한 계산을 수행할 수 있습니다.

  • sin(double a): 주어진 각도의 사인 값을 반환합니다.
  • cos(double a): 주어진 각도의 코사인 값을 반환합니다.
  • tan(double a): 주어진 각도의 탄젠트 값을 반환합니다.
System.out.println("sin(PI) = " + Math.sin(Math.PI));   // 출력: 1.2246467991473532E-16 (사실상 0)
System.out.println("cos(PI) = " + Math.cos(Math.PI));   // 출력: -1.0
System.out.println("tan(PI) = " + Math.tan(Math.PI));   // 출력: -1.2246467991473532E-16 (사실상 0)
  • 참고로 이외에도 더 다양한 삼각함수들이 정의되어 있습니다. (아크사인, 등등)
    • 너무 내용이 방대해지므로 생략합니다..

난수 메서드

난수를 생성하는 기능을 제공합니다.

  • random(): 0.0 이상 1.0 미만의 난수를 반환합니다.
System.out.println("random() = " + Math.random()); // 출력: 0.0 이상 1.0 미만의 값
System.out.println("random() = " + Math.random()); // 출력: 0.0 이상 1.0 미만의 값
  • 난수에 관해선 위 메서드보단 java.utilRandom 클래스를 사용하시는게 좋습니다.

6.2. Random 클래스 (java.util.Random)

  • Random 클래스는 Java에서 난수 생성기를 제공하는 유틸리티 클래스입니다.
    • 이 클래스는 다양한 유형의 난수를 생성할 수 있으며, 난수 생성에 대한 제어(예: 시드 설정)를 통해 예측 가능한 난수를 생성할 수도 있습니다.
  • 참고로 java.lang이 아닌 java.util소속입니다.

Random 클래스의 기본 개요

  • Random 클래스는 임의의 숫자, 실수, 불리언 값을 생성하는 메서드를 제공합니다.
  • Random 클래스는 다음과 같은 방식으로 초기화할 수 있습니다.
    1. 기본 생성자 사용: 기본 시드로 난수 생성기를 초기화합니다. 시드 값은 시스템 시간을 기반으로 설정됩니다. (복잡한 알고리즘이라 자세히 다루진 않습니다)
    Random random = new Random();
    1. 시드값을 지정하여 초기화: 동일한 시드값으로 생성된 Random 객체는 항상 동일한 난수 시퀀스를 생성합니다. 이를 통해 재현 가능한 테스트가 가능합니다.
    Random random = new Random(42); // 시드값 42로 초기화

Random 클래스 난수 생성 메서드

난수 생성 메서드 (정수)

Random 클래스는 다양한 정수 범위 내에서 난수를 생성하는 메서드를 제공합니다.

  • nextInt(): 전체 int 범위에서 난수를 반환합니다. 이 범위는 -2^31에서 2^31-1까지입니다.
  • nextInt(int bound): 0부터 지정된 값(bound) 미만의 정수를 반환합니다. 이 경우 반환되는 값은 [0, bound) 범위에 속합니다.
  • nextInt(bound) + 1: 1부터 지정된 값(bound)까지의 정수를 반환합니다. 이 경우 반환되는 값은 [1, bound] 범위에 속합니다.
System.out.println("(Random) random.nextInt() = " + random.nextInt());
// 출력: -2^31 ~ 2^31-1 범위의 임의의 정수

System.out.println("(Random) random.nextInt(100) = " + random.nextInt(100));
// 출력: 0 ~ 99 사이의 난수

System.out.println("(Random) random.nextInt(100) + 1 = " + (random.nextInt(100) + 1));
// 출력: 1 ~ 100 사이의 난수

난수 생성 메서드 (실수)

Random 클래스는 실수 범위에서 난수를 생성하는 메서드를 제공합니다.

  • nextDouble(): 0.0 이상 1.0 미만의 난수를 반환합니다. 이 범위는 [0.0, 1.0)입니다.
  • nextDouble() * bound: nextDouble()을 사용해 원하는 범위의 난수를 생성할 수 있습니다.
    • 예를 들어, 0.0 이상 bound 미만의 난수를 생성하려면 nextDouble() * bound를 사용합니다.
System.out.println("(Random) random.nextDouble() = " + random.nextDouble());
// 출력: 0.0 이상 1.0 미만의 난수

System.out.println("(Random) random.nextDouble(100) = " + (random.nextDouble() * 100));
// 출력: 0.0 이상 100.0 미만의 난수

난수 생성 메서드 (Boolean)

Random 클래스는 true 또는 false 값을 무작위로 반환하는 메서드를 제공합니다.

  • nextBoolean(): true 또는 false 값을 무작위로 반환합니다.
System.out.println("(Random) random.nextBoolean() = " + random.nextBoolean());
// 출력: true 또는 false

마무리

  • 이번 포스팅에서는 Java의 java.lang 패키지에 속한 주요 유틸리티 클래스들인 Wrapper 클래스들, Class, System, Math, 그리고 java.utilRandom 클래스를 살펴보았습니다. 이 클래스들은 Java 프로그래밍에서 기본적이면서도 강력한 기능을 제공하며, 다양한 상황에서 필수적인 도구들입니다.
  • Wrapper 클래스는 기본 데이터 타입을 객체로 다룰 수 있게 해주며, 오토박싱 및 오토언박싱 기능을 통해 기본 타입과 객체 타입 간의 변환을 쉽게 합니다.
  • Class 클래스는 런타임에 클래스의 구조와 메타데이터를 다루는 데 사용되며, 리플렉션을 통해 동적으로 클래스의 정보를 탐색하고 조작할 수 있습니다.
  • System 클래스는 표준 입출력, 시스템 프로퍼티, 환경 변수, 메모리 관리 등과 관련된 유틸리티 기능을 제공하여 Java 애플리케이션의 실행 환경을 제어할 수 있게 합니다.
  • Math 클래스는 다양한 수학 연산을 수행하는 메서드와 상수를 제공하며, 복잡한 수학적 계산을 간편하게 처리할 수 있도록 도와줍니다.
    • Random 클래스는 다양한 유형의 난수를 생성하는 기능을 제공하여, 게임 개발, 시뮬레이션 등에서 무작위 데이터가 필요한 경우 유용하게 사용됩니다.
  • 이전 포스팅들까지 해서 java.lang의 주요 패키지들을 모두 살펴 보았습니다. 이후엔 열거형 Enum클래스, 날짜 및 시간 메서드, 등을 다루어볼 예정입니다.
profile
일 때문에 포스팅은 잠시 쉬어요 ㅠ 바쁘다 바빠 모두들 화이팅! // Machine Learning (AI) Engineer & BackEnd Engineer (Entry)

0개의 댓글