Java

[Java] Object 클래스와 메서드

DH_0518 2024. 2. 18. 12:04
// Object.class - java17

Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.

Object 클래스는, 클래스 계층 구조의 루트입니다. 모든 클래스는 Object.class를 Super 클래스로 가지고 있습니다. 배열을 포함한 모든 개체는 이 클래스의 메서드를 구현합니다.

 

Java에서 'Object' 클래스는 클래스 계층 구조의 최상위 클래스이자 모든 클래스의 부모 클래스이므로, 모든 클래스는 'Object' 클래스를 직간접적으로 상속받는다. 

 

 

 

Object Class의 메서드

 

Java에서 모든 클래스가 'Object' 클래스를 직간접적으로 상속받으므로, 'Object' 클래스의 메서드 또한 상속받게 된다. 클래스 오브젝트에서 사용할 수 있는 메서드는 다음과 같다

 

 

Object Class가 가지고 있는 public 메서드

  • getClass()
    • 런타임 클래스 객체(Runtime class object)의 정보를 가져온다
    • JVM의 클래스 로더가 힙 영역에 Class 객체를 생성하고, 이 객체의 인스턴스를 런타임 클래스 객체라고 말한다
    • parameter : x
    • return : 실행중인 객체의 클래스 정보를 가지고 있는 Class<?> 객체
    • Runtime Class Object의 메서드
      • getName() : Class의 이름을 반환
      • getFileds() : 클래스의 필드를 반환
      • getConstructors() : 클래스의 생성자를 반환
      • getMethods() : 클래스의 메서드를 반환

getClass() 확인 코드

더보기
// 임의의 Class를 선언
public class ObjectClass {
    public String a = "hello, world";
    public Integer b = 28;

    public ObjectClass(String a, Integer b) {
        this.a = a;
        this.b = b;
    }

    public void method() {
        System.out.println("hello, world");
    }
}


// ObejctClass를 생성하여, [getClass, getName, getFields, getConstructors, getMethods] 메서드의 결과값을 확인
public class ClassTest {
    private static ObjectClass objectClass = new ObjectClass("hello, world", 28);

    public static void main(String[] args) throws NoSuchFieldException {
        // getClass 메서드
        Class<? extends ObjectClass> objClass = objectClass.getClass();
        System.out.println("getClass(): " + objClass);

        // getName 메서드
        String className = objectClass.getClass().getName();
        System.out.println("\ngetName(): " + className);

        // getFields 메서드
        Field[] fields = objectClass.getClass().getFields();
        System.out.println("\ngetFields(): " + fields);
        for (Field field:fields) {
            System.out.println("원소 출력: " + field);
        }

        // getConstructors 메서드
        Constructor<?>[] constructors = objectClass.getClass().getConstructors();
        System.out.println("\ngetConstructors(): " + constructors);
        for (Constructor<?> constructor:constructors) {
            System.out.println("원소 출력: " + constructor);
        }

        // getMethods 메서드
        Method[] methods = objectClass.getClass().getMethods();
        System.out.println("\ngetMethods(): " + methods);
        for (Method method:methods) {
            System.out.println("원소 출력: " + method);
        }
    }
}

 

 

  •  hashCode()
    • 객체의 해시코드를 반환해줌
    • 기본값은 객체의 주소값을 해시코드로 반환시켜주기 때문에, 객체의 주소가 아닌 다른 데이터의 주소를 반환하기 위해서는 오버라이딩하여 재정의 해야한다
    • 오버라이딩하여 같은 '값'을 가지면, 다른 객체더라도 동일한 해시코드를 반환하게끔 사용할 수 있다

hashCode() 확인코드

더보기
// overriding 하지 않은 hashCode 메서드
System.out.println("\nobjectClass.hashCode(): " + objectClass.hashCode());
System.out.println("objectClass2.hashCode() = " + objectClass2.hashCode());


// overriding한 hashCode() 메서드: 필드값 주소를 해시값으로 반환한다
@Override
public int hashCode() {
    return Objects.hash(a, b);
}
System.out.println("\nobjectClass.hashCode(): " + objectClass.hashCode());
System.out.println("objectClass2.hashCode() = " + objectClass2.hashCode());

 

default result

 

overriding result

 

 

  • equals(Object o)
    • 두 객체가 동일한지 비교할 때 사용됨
    • 기본값은 객체의 주소값으로 동등 비교를 진행하기 때문에, 동등 비교 기준을 변경하기 위해서는 오버라이딩하여 재정의 해야한다
    • 오버라이딩하여 같은 '값'을 가지면, 다른 객체더라도 동등하다고 반환하게끔 사용할 수 있다

equals(Object o) 확인코드

더보기
// overriding 하지 않은 equals 메서드 결과
private static ObjectClass objectClass = new ObjectClass("hello, world", 28);
ObjectClass objectClass2 = new ObjectClass("hello, world", 28);
System.out.println("\nobjClass & objClass2 equals(): " + objectClass.equals(objectClass2));


// overrinding한 equals 메서드 : 다른 객체더라도 같은 '값'을 가지면 true를 반환
@Override
public boolean equals(Object obj) {
    if (obj instanceof ObjectClass) {
        ObjectClass objectClass = (ObjectClass) obj;
        return a.equals(objectClass.a) && b.equals(objectClass.b);
    }
    return super.equals(obj);
}
private static ObjectClass objectClass = new ObjectClass("hello, world", 28);
ObjectClass objectClass2 = new ObjectClass("hello, world", 28);
System.out.println("\nobjClass & objClass2 equals(): " + objectClass.equals(objectClass2));

 

default result
overriding result

 

  • toString()
    • 해당 인스턴스의 '클래스이름@인스턴스의 주소(16진수 해시코드)'를 반환한다(print(객체) 와 동일한 결과값)
    • 기본적으로 객체를 출력(println)할 때, 변수에 toString()을 호출하지 않아도 자동으로 붙여서 호출한다
    • 객체의 고유 정보를 출력하고 싶다면, toString을 재정의하여 반환값을 다르게 설정해주면 된다

toString() 확인코드

더보기
// toString 메서드
System.out.println("\ntoString(): " + objectClass.toString());
System.out.println("println: "+ objectClass);

 

toString()의 결과

 

  • notify()
    • 대기 상태인 Thread중, '임으로 하나'를 골라서 다시 RUNNABLE 상태로 변경시키는 역할을 한다
    • 어떤 Thread를 깨울 지 선택할 수 없으므로 제어가 어렵다
    • 메서드를 호출하는 Thread가 반드시 고유 락을 갖고 있어야 한다. 다시 말해, synchronized 블록 내에서 호출되어야 한다
  • notifyAll()
    • notify()와 마찬가지로 대기 상태인 Thread를 다시 RUNNABLE 상태로 변경시키는 역할을 한다
      하지만 notify()와 다르게, '대기 상태인 모든 Thread'를 RUNNABLE 상태로 변경시킨다
    • notifyAll()을 사용한다고 해서 대기상태인 모든 Thread가 '동시에' 동작하는 것은 아니고, 다시 제어권(락)을 획득하기 위해 경쟁한다. 이후 제어권을 획득한 Thread만이 wait()를 리턴시키고 다음 로직을 수행할 수 있다
    • 메서드를 호출하는 Thread가 반드시 고유 락을 갖고 있어야 한다. 다시 말해, synchronized 블록 내에서 호출되어야 한다
  • wait()
    • 자원을 소유한 Thread가, 자신의 제어권을 양보하고 대기상태로 들어가기 위해 사용된다
    • 메서드를 호출하는 Thread가 반드시 고유 락을 갖고 있어야 한다. 다시 말해, synchronized 블록 내에서 호출되어야 한다

 

 

 



 

 

 

 

 

 

복습 Question

  • 모든 클래스들이 공통적으로 상속하는 메서드는 어떤게 있을까?
  • equals()와 hashcode()는 기본적으로 '주소값'으로 동작하게 된다. 이를 '값'으로 동작하게 하려면 어떻게 재정의 코드를 작성 해야할까?
  • wait(), notifyAll()을 사용하여 다음의 요구사항을 충족시키는 블로킹 큐를 구현해보자
    (참고 : http://happinessoncode.com/2017/10/05/java-object-wait-and-notify/)
    • 생성 시점에 용량(capacity)이 결정된다.
    • 큐가 비어있을 때 요소를 빼내려고 하면 빼낼 요소가 들어올 때까지 스레드가 블로킹된다.
    • 용량이 꽉 찼을 때 요소를 추가하려고 하면 빈 공간이 생길 때까지 스레드가 블로킹된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

Reference

 

[Java] Object 클래스 wait, notify, notifyAll | 👨🏻‍💻 Tech Interview

[Java] Object 클래스 wait, notify, notifyAll Java의 최상위 클래스 = Object 클래스 Object Class 가 갖고 있는 메서드 toString() hashCode() wait() 갖고 있던 고유 lock 해제, Thread를 잠들게 함 notify() 잠들던 Thread 중 임

gyoogle.dev

 

[Java]Object 클래스의 getClass 메서드

Object 클래스의 getClass 메서드 java.lang 패키지에 존재하는 Object 클래스의 getClass() 메서드를 사용하면, 실행 중인 클래스 객체의 정보를 가져올 수 있습니다. public final native Class getClass(); getClass()

developer-talk.tistory.com

 

[자바 무료 강의] 모든 클래스는 Object 클래스를 상속받는다

모든 클래스는 Object 클래스를 상속 받습니다. 그러므로 Object 클래스에 대해 간략히 알아봅시다.

www.codelatte.io

 

Java Object 클래스의 wait과 notify의 사용법

Object의 wait, notify와 notifyAll자바의 최상위 클래스인 Object에는 몇 가지 메서드가 존재한다. 널리 쓰이는 toString()은 객체를 문자열로 표현할 때, hashCode()는 객체의 해시 값을 계산할 때 사용된다.

happinessoncode.com