[Java 응용] java.lang 패키지 - 1. Object 클래스

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

0. Java.lang 패키지 개요

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

1. Object 클래스

  • Object 클래스는 Java에서 모든 클래스의 최상위 부모 클래스입니다. 모든 클래스는 Object 클래스를 상속받으며, Object 클래스에 정의된 메서드들은 모든 Java 객체에서 사용할 수 있습니다.

1.1 Object 클래스의 다형성

  • Java에서 다형성(Polymorphism)은 같은 인터페이스나 부모 클래스를 통해 여러 다른 객체를 동일한 방식으로 다룰 수 있게 해주는 개념입니다.
    • Object 클래스는 모든 클래스의 부모이기 때문에, 모든 Java 객체는 Object 타입으로 참조될 수 있습니다.
    • 이는 Java의 강력한 다형성 지원을 가능하게 합니다.

Object 클래스의 다형성 예시 코드

Object obj1 = new String("Hello");
Object obj2 = new Integer(10);
Object obj3 = new ArrayList<>();
  • 위 코드에서 obj1, obj2, obj3은 각각 String, Integer, ArrayList 객체를 참조하지만, 모두 Object 타입으로 선언되었습니다.
    • 이는 Java의 다형성 덕분에 가능하며, 다양한 객체들을 공통된 방식으로 처리할 수 있게 합니다.

1.2 Object 클래스의 배열

  • Java에서 배열은 객체로 간주됩니다.
  • 모든 배열은 Object 클래스의 하위 타입으로, 배열 자체가 Object로 취급됩니다.
    • 따라서 배열을 Object 타입으로 참조할 수 있으며, 배열의 요소도 Object 타입으로 처리할 수 있습니다.

Object 클래스의 배열 예시 코드

int[] intArray = {1, 2, 3};
Object objArray = intArray; // 배열을 Object로 참조

System.out.println(objArray instanceof Object); // true
  • 위 코드에서 intArray는 int 타입의 배열이지만, 이를 Object로 참조할 수 있습니다.
    • 이는 배열이 객체로서 Object의 하위 타입임을 보여줍니다.

배열과 다형성

  • 배열 또한 다형성의 혜택을 누릴 수 있습니다.
    • 예를 들어, 서로 다른 타입의 배열을 Object 배열에 담아 처리할 수 있습니다.
Object[] objects = new Object[3];
objects[0] = new String("Hello");
objects[1] = new Integer(10);
objects[2] = new int[]{1, 2, 3};
  • 위 코드에서 objects 배열은 String, Integer, int[] 타입의 객체들을 하나의 배열로써 관리할 수 있습니다.

1.3 Object 클래스와 OCP(Open-Closed Principle)

  • OCP(Open-Closed Principle)란?
    • OCP(개방-폐쇄 원칙)는 소프트웨어 설계 원칙 중 하나로, 클래스는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다는 원칙입니다.
    • 즉, 새로운 기능을 추가할 때 기존 코드를 수정하지 않고도 확장이 가능해야 합니다.

Object 클래스와 OCP

  • Object 클래스는 OCP 원칙을 잘 따르는 구조를 가지고 있습니다.
  • Object 클래스의 메서드들은 서브클래스에서 쉽게 확장할 수 있도록 설계되었습니다.
    • 예를 들어, toString(), equals(), hashCode() 등의 메서드는 기본 구현을 제공하지만, 서브클래스에서 오버라이드하여 원하는 동작을 구현할 수 있습니다.
public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }
}
  • 위 예시에서 Person 클래스는 Object 클래스의 toString() 메서드를 오버라이드하여 자신만의 문자열 표현을 정의하고 있습니다.
    • 이는 기존 Object 클래스를 수정하지 않고도 새로운 기능을 확장한 예입니다.

1.4 Object 클래스 기본 제공 메서드들

1. toString() 메서드

  • toString() 메서드는 객체의 문자열 표현을 반환하는 메서드입니다.
  • Object 클래스에서 기본적으로 제공되는 toString() 메서드는 클래스 이름과 해시 코드를 반환합니다.
// java.lang.Object 中 toString() 메서드
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
  • toString() 메서드를 오버라이드하여 객체의 속성이나 상태를 의미 있는 문자열로 반환할 수 있습니다.
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}
  • 위 예시에서 Person 클래스는 toString() 메서드를 오버라이드하여 객체의 상태를 표현하는 문자열을 반환하도록 구현되었습니다.

2. equals() 메서드 - 동일성과 동등성

  • equals() 메서드는 두 객체가 "동일"한지 "동등"한지를 비교하는 메서드입니다.
    • 동일성(identity): 동일한 "메모리 주소"를 가리키는지 비교합니다.
    • 동등성(equality): 동일한 "값"을 가지는지를 비교합니다.
  • 기본적으로 Object 클래스의 equals() 메서드는 동일성(identity)을 비교하지만, 이를 오버라이드하여 객체의 동등성(equality)을 비교할 수 있습니다.
// java.lang.Object 中 equals() 메서드
    public boolean equals(Object obj) {
        return (this == obj);
    }
  • 오버라이드 예시
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
  • 위 코드에서 Person 클래스는 equals() 메서드를 오버라이드하여 두 객체의 동등성을 비교하도록 구현되었습니다.
    • 구체적으로는 5가지 정도의 규칙이 존재하지만, 이를 모두 외워서 활용하는 경우는 거의 없어서, generator 단축키를 통해 자동으로 생성하여 이를 쓰는 편이 좋습니다.
      • IntelliJ 단축키 : command+N(Mac), Alt+Insert(Win/Linux)

3. 나머지 Method들

  • clone(): 객체의 복제를 지원하는 메서드입니다. Object 클래스에서 제공되며, Cloneable 인터페이스를 구현한 객체만 사용 가능합니다.
    • 실제로 쓸일은 거의 없습니다.
    • 다만, 기본형 타입의 배열(int[], 등..)의 깊은복사(deepcopy)를 수행할때 간편하게 사용할 수 있어 종종 쓰이긴 합니다. (참조형은 참조값만 복사하게 됩니다)
@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}
  • hashCode(): 객체의 해시 코드를 반환하는 메서드입니다.

    • 해시 코드는 주로 해시 기반 컬렉션(HashMap, HashSet 등)에서 사용됩니다.
      • 참고로 해시테이블이나 트리 자료형에선 거의 필수적으로 오버라이딩 해주어야 합니다. (안해주면 주소값으로 계산하거나 비교하게 되기 때문인데, 이런게 있구나 정도로 넘어가주시길!)
    • equals() 메서드를 오버라이드한 경우 hashCode() 메서드도 함께 오버라이드하는 것이 일반적입니다.
  • getClass(): 런타임 시 객체의 클래스 정보를 반환하는 메서드입니다.

Class<?> clazz = obj.getClass();
  • notify(), notifyAll(), wait(): 스레드 간의 동기화를 위해 사용되는 메서드들입니다. 주로 멀티스레드 환경에서 스레드 간의 작업 조정에 사용됩니다.
    • 이 메서드들은 주로 멀티스레딩 프로그래밍에서 자주 사용됩니다.
synchronized(obj) {
    obj.wait();
    obj.notify();
}

마무리

  • 이번 포스트에서는 Java.lang 패키지 개요와 Object 클래스에 대해서 정리해보았고, 다음 포스트에서는 Java.lang 패키지 중 String 클래스에 대해서 정리해 보도록 하겠습니다.
    • Object 클래스는 모든 Java 클래스의 최상위 부모 클래스이므로, 이 클래스에 정의된 메서드들은 Java에서 매우 중요합니다.
    • 다음 포스트에서 다룰 String 클래스Object 클래스의 메서드를 상속받고 사용하므로, Object 클래스에 대한 이해는 Java 프로그래밍의 기초이고 상당히 중요한 의미를 가집니다.
profile
일 때문에 포스팅은 잠시 쉬어요 ㅠ 바쁘다 바빠 모두들 화이팅! // Machine Learning (AI) Engineer & BackEnd Engineer (Entry)

0개의 댓글