[Java] java.lang 패키지 정리: Object, String, Math 클래스 총정리

2025. 5. 26. 14:52·공부/☕Java

✅ 1. java.lang 패키지란?

import java.lang.*;
  • Java에서 가장 기본적이고 자주 사용되는 클래스들을 모아놓은 패지키를 의미한다.
  • java.lang 패키지는 모든 클래스의 자동으로 import가 되기 때문에 별도로 import를 이용해 사용을 하지 않아도 된다.
  • 위의 코드처럼 컴파일 시 모든 코드에 해당 import 문이 상단에 붙게 된다.
  • java.lang 패키지 내부에는 String, Object, Thread, System 등 자바에서 가장 기본이 되는 클래스들이 들어가 있음.

✅ 2. Object 클래스

// 컴파일 전
public class MyClass {
}
// 컴파일 후 -> .class
public class MyClass extends Object {
}
  • 자동으로 모든 클래스의 조상이 되는 클래스이며, 클래스 계층 구조에서 루트가 되는 클래스이다.
  • 해당 Object 클래스는 모든 클래스가 자동으로 상속을 받고 있기에 상속 구조에서 최상위 클래스가 된다.
  • 이건 컴파일 시점에 컴파일러가 자동으로 상속이 없는 클래스에 extends Object를 자동으로 붙여주기 떄문이다.

(1) Object 클래스가 가지고 있는 주요 메서드

protected Object clone() // 객체를 복제하여 반환
public boolean equals(Object obj) // 같은 객체인지 참조값으로 비교
public int hashCode() // 객체를 식별하는 정수값을 반환
public String toString() // 객체를 문자열로 반환

 

(2) toString()

// Object.class
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
  • 객체를 문자열로 표현한 결과를 반환하는 메서드이다.
  • 클래스이름@16진수해시코드로 표현을 해서 String 즉, 문자열로 반환을 해준다.

(3) equals()

// Object.class
public boolean equals(Object obj) {
    return (this == obj);
}
  • 두 객체 변수를 비교해서, 변수가 가리키는 객체의 참조값이 같으면 true를 반환 ( 즉, 객체 검증을 할 때 사용 )
  • 해당 메서드는 자바의 == (동등비교연산자) 를 사용해서 비교를 하고 있음. 즉, 그냥 동등비교연산자라고 생각하면됨.

(4) clone()

// Object.class
@IntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
// Cloneable interface
package java.lang;
public interface Cloneable {
}
  • Java에서 객체를 복제하기 위해 사용하는 메서드이다.
  • 모든 클래스는 Object를 상속 받고 있기 때문에 모든 클래스에서 사용이 가능하지만 조건이 붙는다.
  • 해당 클래스가 Cloneable 인터페이스를 implements 해야하며, 해당 clone()를 직접 구현해야지만 사용이 가능하다.
  • clone을 하면, 해당 객체 내부의 들어가있는 값 자체도 복사가 되며, 참조값이 다른 똑같이 생긴 객체를 만들어준다.
  • 이러한 부분은 예외처리 할 때 try() 메서드문의 자동 인터페이스 -> close() 메서드와 같은 방식으로 동작을 한다.

(5) getClass()

// Object.class
@IntrinsicCandidate
public final native Class<?> getClass();
  • 현재 객체의 실제 클래스 정보를 반환한다. 즉, 클래스 정보를 가진 Class 객체를 리턴하게 된다.
  • 해당 메서드는 native 즉, JVM이 네이티브 코드(C/C++)로 구현했다는 의미이다.
  • 즉, Java 소스 코드가 아닌 JVM 내부에서 다른 언어를 통해 처리가 되므로, 메서드 바디는 확인 할 수 없다.
  • 반환 타입 Class<?>은 보통 Java의 리플렉션에서 사용이 된다.
  • JVM은 Dog클래스가 있다치면, 클래스를 메모리에 로드하면서 Class<Dog> 객체도 내부에서 자동으로 생성을 해둔다.
  • 이건 네이티브 영역에서 진행이 된다.
  • JVM은 클래스를 처음 "로드(load)"할 때, Class<?> 객체를 내부에서 생성하며, 그 안에 해당 클래스의 모든 정보를 "내장된 구조"를 통해 채워 넣습니다.
  • "JVM은 클래스를 하나의 데이터 객체로 다룰 수 있도록 Class<?>라는 구조를 미리 설계해놓고, 클래스를 로딩하면서 거기에 정보를 채워넣는 일종의 프레임워크처럼 작동한다."

✅ 3. String 클래스

  • 문자열을 표현하고 처리하기 위한 클래스를 의미한다.
  • String 클래스 생성 방식은 리터럴 방식과 객체 생성 방식 두 가지 방식이 존재한다.
  • String은 불변클래스이며, 필드와 클래스에는 final로 값의 변경을 막고 있음.

(1) String 리터럴 생성 방식

String a = "Hello";
  • 리터럴 방식은 해당 문자열 값이 String Constant Pool(문자열 상수 풀)에 저장이 된다.
  • 상수풀에 존재하는 해당 문자열 값을 다른 변수로 이용을 하게 된다면 재사용을 하게 된다.
  • 즉, Hello 라는 문자가 존재하면 해당 문자를 변수들이 참조해서 이용을 하게 된다는 의미이다.
  • 문자열은 반복되는 문자가 많이 선언될 수 있기에, 객체로써 가지고 있게 되면 같은 문자 객체를 반복적으로 만들게됨.
  • 즉, 메모리 측면에서 많은 비효율과 성능의 떨어짐이 존재할 수 있음.
  • 그래서 상수풀을 활용하면, 메모리 효율이 높고 속도가 빠르다는 장점이 있음.

[1] String Constant Pool(문자열 상수 풀) 이란?

  • 처음 String 리터럴 방식 또는 intern() 메서드가 호출이 되면 그때 해당 상수풀이 만들어진다.
  • 즉, 클래스로더가 해당 클래스를 처음 로드 하는 시점에 상수풀이 만들어진다고 보면 된다.
  • 해당 상수풀은 반복적으로 만들어지는 문자열을 

[2] intern() 메서드란?

// String.class
public native String intern();
  • new String("Hello")로 만들어진 객체 문자열을 intern() 메서드를 통해 상수풀에 넣을 수 있게 됨.
  • String 클래스의 메서드로, native 코드 즉, 메서드 바디는 C랑 C++로 구현 되어있으며, 해당 코드를 실행하는 메서드임.
  • JVM 에서 해당 C랑 C++로 구현 되고, 컴파일 된 코드를 호출하는 코드가 내장이 되어있음.
  • 즉, 파일을 읽는 등의 코드는 내장이 되어있어서, 바로 메서드 호출로 해당 C++ 코드를 실행 할 수 있음.
  • 왜냐하면, 이미 JVM이 해당 코드를 JVM 내부에서 가지고 있기 때문임.

(2) String 객체 생성 방식

String b = new String("hello");  // Heap 메모리 새 객체
  • 해당 문자열을 새로운 Heap 메모리에 새로운 객체로 만드는 방식이다.
  • 즉, 같은 문자열을 똑같은 방식으로 생성을 하게 되도 주소값이 다른 새로운 객체가 만들어진다.
String a = new String("hello");  // Heap 메모리 새 객체
String b = new String("hello");  // Heap 메모리 새 객체
System.out.println(a == b);            // false
  • String 객체 생성 방식은 동일한 문자열을 재사용 할 수 없는 부분이 매우 큰 단점이라 보통은 사용이 되지 않는 방식이다.
  • 그렇기 때문에 이러한 문제를 해결하기 위해 객체로 생성한 문자열을 상수풀에 넣는 방법이 존재한다.
  • 이 방법은 위에 설명에서 나온 intern() 메서드를 호출해서 상수풀에 넣는 방식이다.
String a = "hello";              // Constant Pool 활용 (리터럴)
String b = new String("hello");  // Heap 메모리 새 객체

System.out.println(a == b);            // false
System.out.println(a == b.intern());   // true

 

(3) String - 문자열 비교 메서드

[1] compareTo 메서드 - 정수값 반환

String a = "Hello";
String b = new String("Hello");
System.out.println(a.compareTo(b)); // 결과: 0
  • 두 문자열이 같으면 0을 리턴하고, 다르면 0이 아닌 정수값을 리턴함.
  • 주소값이 아닌 내부의 값 자체를 비교함.

[2] equals 메서드 - 논리값 반환

String a = "Hello";
String b = new String("Hello");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
  • Object 클래스의 equals() 를 재정의 하고 있어, 주소값이 아닌 문자열 자체의 값을 비교함.

✅ 4. StringBuffer 클래스

 (1) String 클래스의 문제점

  • String의 문자열 상수풀은 문자열의 중복값 저장을 방지하기 위해서 사용을 한다.
  • 하지만, 문자열이 늘어남에 따라 새로운 객체가 생성되는 문제점은 그대로 있다.
  • 이러한 문제로인해, 잦은 변수값의 수정은 새로운 String 객체를 만들기 때문에 성능의 저하를 일으킬 수 있다.

(2) StringBuffer 클래스

StringBuffer sb = new StringBuffer(); // 초기 빈 문자열 버퍼

sb.append("안녕하세요");
sb.append(" ");
sb.append("XXX입니다.");
sb.insert(6, "[개발자] ");
sb.replace(0, 5, "Hello");
sb.delete(17, sb.length()); // 마지막 문장 일부 삭제

System.out.println(sb.toString());  // 출력 결과: Hello [개발자] XXX
  • StringBuffer 클래스는 객체 생성 이후 문자열을 변경할 수 있는 클래스이다.
  • 내부적으로 문자열을 저장하기 위해 크기가 조절되는 버퍼(배열이라고 보면됨)를 사용을 한다.
  • 문자열을 자주 수정해야 하는 상황에서 많이 쓰이는 클래스라고 보면 된다.
  • 메서드를 통해 문자를 추가하게 되면, 객체를 생성하지 않고 내부의 버퍼에 추가가 된다고 보면 된다.

(3) StringBuilder 클래스

  • StringBuffer 클래스와 거의 똑같이 생긴 클래이며, 차이로는 동기화 여부에서의 차이가 있다.
  • StringBuffer은 스레드 안전하지만, StringBuilder은 비동기로 스레드 안전하지 못하다는 특징이 있음.
  • 대신에, 속도 측명에선 StringBuilder가 빠르다.
  • 멀티스레드에선 StringBuffer를 사용하며, 단일 스레드에선 StringBuilder를 주로 사용함.
  • 그래서 보통은 StringBuilder를 사용하지만, 스레드 안정성이 정말 필요한 경우 StringBuffer를 쓴다.

(4) String vs StringBuffer vs StringBuilder

public class Main {
    public static void main(String[] args) {

        final String tmp = "test";
        long start, end;

        String str = new String();
        StringBuffer sb1 = new StringBuffer();
        StringBuilder sb2 = new StringBuilder();

        start = System.nanoTime();
        for(int i = 0; i < 100; i++) str += tmp;
        end = System.nanoTime();
        System.out.println((end-start) / 1000000.0 + " msecs"); // 4.155299 msecs

        start = System.nanoTime();
        for(int i = 0; i < 100; i++) sb1.append(tmp);
        end = System.nanoTime();
        System.out.println((end-start) / 1000000.0 + " msecs"); // 0.054601 msecs

        start = System.nanoTime();
        for(int i = 0; i < 100; i++) sb2.append(tmp);
        end = System.nanoTime();
        System.out.println((end-start) / 1000000.0 + " msecs"); // 0.047 msecs
    }
}
  • String = 4.155299 msecs
  • StringBuffer = 0.054601 msecs
  • StringBuilder = 0.047 msecs
  • StringBuilder가 가장 빠르고 다음으로 StringBuffer가 빠르고 다음으로 String이 나왔음.

✅ 5. 포장 클래스 ( 래퍼 클래스 )

Double double = new Double(2.59) // 생성자 방식, 권장 안됨
DOuble double = Double.valueOf(10.4); // ValueOf() 사용 방식 권장
Double double = 3.14; // 자동 boxing
  • 기본자료형을 참조자료형으로 표현하기 위한 클래스이다. 기본자료형은 int, double, char, boolean 등을 의미함.
  • 기본형과 상응하는 객체 사이의 형변환 기능을 제공함.
  • 메서드의 인자로 참조형 즉, 객체 자체가 필요한 경우 해당 기본자료형을 참조형으로 박싱해서 보내줄 수 있음.
  • 또한. 래퍼 클래스는 다양한 메서드를 제공을 해줌.
  • Number 추상 클래스를 상속 받아서 구현 된 클래스들을 의미함.

(1) 박싱(Boxing)

Double d = Double.valueOf(10.4); // ValueOf() 사용 방식 권장
Double pi = 3.14; // 자동 boxing
// 내부적으로 Double.vlauleOf(3.14) 로 처리가 됨.
  • 기본자료형의 값을 박싱해서 객체로 만드는 방법을 의미하며, 자동과 valueOf() 방식이 존재한다.
  • 자동 또한 어차피 valueOf() 방식을 활용하기 때문에, valueOf()가 매우 중요하게 작용됨.
  • 인자에 전달되거나 변수에 대입될 때 자동으로 박싱되어서 적용이 됨.

(2) 언박싱(Unboxing)

Double pi = 3.14; // 자동 boxing
double d = Double.doubleValue(pi); // doubleValue() : 기본자료형으로 변경 메서드
double d = pi; // 자동 unboxing
  • 래퍼클래스의 참조값을 기본자료형의 값으로 변경하는 것을 의미하며, 자동과 doubleValue() 방식이 존재함
  • 박싱과 마찬가지로, 자동 언박싱 또한 doubleValue()가 내부적으로 동작한다고 보면됨.
  • 마찬가지로 인자에 전달되거나 변수에 대입될 때 자동으로 박싱되어서 적용이 됨.

✅ 6. System 클래스

  • System 클래스는 자바에서 매우 중요한 유틸리티 클래스로, 운영체제와의 인터페이스를 일부 제공하는 표준 입출력, 시스템 속성, 시간 측정, 종료 등 다양한 기능을 제공한다. 한마디로, 자바 프로그램이 JVM 및 OS와 상호작용하는 수단 중 하나임.
  • 모든 멤버는 static, 사용할 때 객체를 생성할 필요는 전혀 없음.
  • 표준 입출력 객체 제공, JVM 속성과 시스템 환경 변수의 사용과 제어, 배열 복사, 시간 조회, 프로그램의 제어 등을 해줌.

(1) System 클래스 - 표준 입출력 필드

  • System.in: 표준 입력 스트림으로 InputStream 유형, 키보드로부터 입력을 받을 때 사용함.
  • Systme.out: 표준 출력 스트림 PrintStream 유형, 화면에 데이터를 출력할 때 사용함.
  • System.err: 표준 에러 출력 스트림 PrintStream 유형, 오류 메시지를 화면에 출력할 때 사용함.

✅ 7. 그 외

  • java.lang 패키지에는 그 외 Process, Thread, Exception, Package, Class, Math 등이 있음.

'공부 > ☕Java' 카테고리의 다른 글

[Java] java.nio 사용법 | Path, Files, FileChannel 예제 모음  (3) 2025.05.30
[Java] java.io 패키지 입출력 스트림 쉽게 이해하기  (2) 2025.05.28
[Java] 자바 함수형 인터페이스와 람다식(Lambda Expression) 쉽게 배우기  (1) 2025.05.23
[Java] 제네릭(Generic) 문법 정리: 클래스, 메서드, 제한까지  (0) 2025.05.23
[Java] 익명 클래스(Anonymous Class)  (1) 2025.05.22
'공부/☕Java' 카테고리의 다른 글
  • [Java] java.nio 사용법 | Path, Files, FileChannel 예제 모음
  • [Java] java.io 패키지 입출력 스트림 쉽게 이해하기
  • [Java] 자바 함수형 인터페이스와 람다식(Lambda Expression) 쉽게 배우기
  • [Java] 제네릭(Generic) 문법 정리: 클래스, 메서드, 제한까지
junbin2
junbin2
java.lang.NullPointerException
  • junbin2
    bin's Development Diary
    junbin2
  • 전체
    오늘
    어제
    • 전체보기 (233)
      • 방송통신대학교 (87)
        • ⚙️컴퓨터의 이해 (11)
        • 💻컴퓨터과학 개론 (15)
        • 🔢자료구조 (14)
        • 🧬알고리즘 (10)
        • ⚙️운영체제 (14)
        • 🕸️이산수학 (11)
        • 🌍유비쿼터스 컴퓨팅 (11)
        • 🖥️컴퓨터과학과 (1)
      • 공부 (72)
        • 📚백엔드 공부 (6)
        • ☕Java (23)
        • 🌳Spring (13)
        • ⚙️C (12)
        • ⚡Python (15)
        • JavaScript (1)
        • 🛢️Database (0)
        • Algorithm Problem Solving (2)
      • 네트워크 (7)
        • 📜HTTP (7)
      • 스파르타코딩클럽 (64)
      • 정보 (2)
      • 정리가 필요한 글 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    컴퓨터과학 개론
    그래프
    방송통신대학교
    운영체제
    이산수학
    파이썬
    컴퓨터의 이해
    Python
    자바
    자료구조
    방통대
    함수
    C언어
    컴퓨터과학과
    배열
    알고리즘
    Java
    방송대
    spring
    유비쿼터스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
junbin2
[Java] java.lang 패키지 정리: Object, String, Math 클래스 총정리
상단으로

티스토리툴바