[Java] Object 클래스

2024. 4. 7. 20:40· Java
목차
  1. Object 클래스란
  2. java.lang 패키지
  3. java.lang.Object
  4. References
728x90

Object 클래스란

Object 클래스는 자바의 클래스 계층의 뿌리이다.

Object 클래스는 자바 클래스들의 조상이라고 할 수 있다. 명시적으로 Object 클래스를 import 하지 않더라도 이미 Object 클래스는 import가 되어 있다. 그렇기 때문에 Object 클래스에 속하는 클래스 및 메서드들은 import 없이 사용이 가능하다.

 

 

java.lang 패키지

java.lang 패키지의 Object 클래스 내의 클래스들의 계층 구조

 

Object.lang 패키지는 Object 클래스에서 가장 기본적인 동작을 수행하는 클래스들을 모아놓은 패키지이다. 이번 포스팅에서 다룰 Object 클래스 또한 java.lang 패키지에 속하는 클래스이다. Object 클래스가 별도의 import 과정 없이 사용 가능한 것도 Object 클래스가 속하는 java.lang 패키지가 import 없이 자바 프로그램에 자동으로 포함되기 때문이다.

 

 

java.lang.Object

java.lang 패키지의 클래스들의 import 없이 바로 사용 가능하기 때문에 java.lang.Object 또한 그러하다.

java.lang.Object의 메서드는 총 11가지가 있다.

 

clone()

object의 복사본을 생성하고 return 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Main {
 
    public static void main(String[] args) {
 
        User user = new User("pseudocode", 99);
        User userCopy = user.clone();
        System.out.println(user);
        System.out.println(userCopy);
    }
 
    static class User implements Cloneable {
        String name;
        int age;
 
        User(String name, int age) {
            this.age = age;
            this.name = name;
        }
 
        @Override
        public User clone() {
            try {
                User clone = (User) super.clone();
                // TODO: copy mutable state here, so the clone can't change the internals of the original
                return clone;
            } catch (CloneNotSupportedException e) {
                throw new AssertionError();
            }
        }
    }
}
Colored by Color Scripter
cs

 

위의 코드와 같이 User객체를 생성하고 clone을 통해 복사 객체인 userCopy를 생성해 보았다.

주의할 점은 clone 메서드를 사용하기 위해서는 사용하려는 객체에 Cloneable 인터페이스를 상속해 주고 clone() 메서드를 복사하려는 객체에 맞춰서 재정의를 해줘야 한다.

 

두 객체를 출력해 보면 서로 다른 객체인 것을 확인할 수 있다. 즉 deep copy(깊은 복사)가 clone()을 통해서 이루어지는 것을 확인할 수 있다.

깊은 복사(deep copy) vs 얕은 복사(shallow copy)


얕은 복사의 경우 객체의 필드들을 복사하는 것이나 필드가 참조형 변수일 경우 값 자체를 복사하는 것이 아닌 해당 변수의 '참조'를 복사한다. 간단하고 빠르며 메모리를 사용량이 적다는 장점이 있으나 참조를 공유한다는 점 때문에 예기치 못한 부작용이 발생할 수 있다. 

깊은 복사의 경우 객체와 해당 객체의 하위 객체까지 모두 복사한다. 즉 복사된 객체는 원본 객체와 다른 완전한 별개의 독립적인 객체가 된다. 메모리 사용량이 많지만 복잡한 구조의 객체 복사 시에 유용하다.

 

 

toString()

객체를 문자열화한 결과를 반환한다.

반환할 때

getClass().getName() + '@' + Integer.toHexString(hashCode())

의 결과를 반환한다. getClass.getName()으로 해당 클래스의 이름과 해당 객체의 해시코드를 문자 '@'와 합쳐서 반환한다.

 

1
2
3
4
5
6
7
8
9
public class Main {
 
    public static void main(String[] args) {
 
        User user = new User("pseudocode", 99);
        System.out.println(user.toString());
        System.out.println(user.getClass().getName()+'@'+Integer.toHexString(user.hashCode()));
    }
}
Colored by Color Scripter
cs

 

같은 값이 나오는 것을 확인할 수 있다.

 

 

.equals(Object obj)

두 객체가 같은지 비교할 때 사용되는 메서드이다.

 

equals() 메서드의 디폴트가 두 객체의 참조가 같은지 비교(두 객체가 메모리 상에서 같은 위치를 가르키는지) 하는 것이기 때문에 값을 기준으로 동등 비교를 하기 위해서는 오버라이딩을 통해 메서드 재정의를 해야 한다. 일반적으로 참조를 기준으로 비교할 때 '==' 연산자를 사용하고 값을 기준으로 비교할 때는 equals() 메서드를 재정의하여 사용한다.

 

equals()를 통해 비교할 때, 객체의 주소를 비교하여 같은 객체인지 판단하기 때문에 객체 간 주소가 다르면 false가 출력된다.

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
 
    public static void main(String[] args) {
 
        User user1 = new User("pseudocode");
        User user2 = new User("pseudocode");
        User user3 = user1;
        System.out.println(user1.equals(user2));
        System.out.println(user1.equals(user3));
 
    }
}
Colored by Color Scripter
cs

 

user1과 user2는 서로 다른 객체이기 때문에 주소 또한 다르기 때문에 다른 객체로 인식하여 false가 출력된다.

user1을 참조하는 user3는 주소가 같기 때문에 서로 같은 객체로 인식하여 true가 출력된다.

 

user1과 user2는 내부 값이 같지만 참조 값이 서로 다르기 때문에 equals 메서드로 비교할 경우 서로 다른 객체로 인식된다. 같은 객체로 인식하기 위해서는 아래처럼 오버라이딩을 통한 재정의가 필요하다.

import java.util.Objects;

public class EqualsTest {

    public static void main(String[] args) {

        User user1 = new User("pseudocode");
        User user2 = new User("pseudocode");
        System.out.println(user1.equals(user2)); // true
    }

    static class User {
        String name;
        User(String name) {
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            // 같은 객체인 경우 true 반환
            if(this == o) {
                return true;
            }
            // o가 null이거나 class가 다를 경우 false 반환
            if(o == null || getClass() != o.getClass()) {
                return false;
            }
            User u = (User) o; // User 타입으로 캐스팅
            return Objects.equals(name, u.name); // name 필드 값이 같은지 비교
        }
    }
}

 

 

.finalize()

자바에서 더 이상 참조되지 않는 객체가 존재할 때 Garbage Collector가 메모리를 자동으로 수거한다. GC가 수행되기 전에 호출되어 객체가 점유하고 있던 자원들을 해제할 때 사용되는 메서드가 finalize() 메서드이다.

finalize()는 객체소멸자라고도 부른다. 다만 해당 메서드는 JDK 9 버전부터 deprecated 처리가 되어 Object 클래스에서 제거될 예정이다.

 

.getClass()

해당 객체의 런타임 클래스를 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.*;
 
public class Main {
 
    public static void main(String[] args) {
 
        User user = new User("psuedocode");
        ArrayList<Integer> arrayList = new ArrayList<>();
        HashSet<Integer> hashSet = new HashSet<>();
 
        System.out.println(user.getClass());
        System.out.println(arrayList.getClass());
        System.out.println(hashSet.getClass());
    }
 
    static class User {
        String name;
 
        User(String name) {
            this.name = name;
        }
    }
}
Colored by Color Scripter
cs

각 객체가 속한 패키지, 클래스를 반환한다.

 

.hashCode()

해당 객체의 해시코드 값을 반환한다.

자바에서의 모든 객체는 JVM에 의해 고유번호가 자동으로 생성된다. 이때 생성되는 고유번호를 해시코드라고 한다.

해시코드는 32비트의 고유한 정수 값이며, 객체 내부 주소를 정수로 변환한 값이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Main {
 
    public static void main(String[] args) {
 
        User user = new User("psuedocode");
        User user1 = new User("hahaha");
        System.out.println(user.hashCode());
        System.out.println(user1.hashCode());
    }
 
    static class User {
        String name;
 
        User(String name) {
            this.name = name;
        }
    }
}
Colored by Color Scripter
cs
각 객체의 주소를 나타내는 해시코드

 

 

hashCode() 메서드도 마찬가지로 오버라이딩 가능하다. 주로 equals() 메서드를 재정의할 때 hashCode() 메서드 또한 같이 재정의한다.

equals() 메서드가 객체 내부 값을 기준으로 비교하기 때문에 객체 자체의 해시코드 값을 반환하는 디폴트 hashCode() 메서드도 객체 내부 값의 해시코드 값을 반환하도록 변경해야 하는 것이 바람직하다.

import java.util.Objects;

public class EqualsTest {

    public static void main(String[] args) {

        User user1 = new User("pseudocode");
        User user2 = new User("pseudocode");
        System.out.println(user1.hashCode() == user2.hashCode()); // true
    }

    static class User {
        String name;
        User(String name) {
            this.name = name;
        }

        @Override
        public int hashCode() {
            return Objects.hash(name); // 객체의 name값을 기반으로 해시 코드 생성
        }
    }
}

 

 

🌱스레드 관련 포스팅

.notify() / .notifyAll()

잠들어 있는 스레드 하나를 깨운다. notifyAll()은 잠들어 있는 모든 스레드를 깨운다.

만약 여러 개의 대기 상태의 스레드가 존재한다면 그중 하나를 임의로 선택하여 깨운다.

현재 락을 가지고 있는 스레드가 작업을 끝내기 전까지는 깨운 스레드가 동작하지 않는다. notify 사용 시 잠들어 있는 스레드 중 임의로 하나를 깨우는 것이기 때문에 제어가 어렵다는 단점이 있다.

 

.wait()

현재 스레드를 다른 스레드가 notify()나 notifyAll()을 통해 깨우기 전까지 대기 상태(wait)로 전환시킨다. 

 

.wait(long timeout)

현재 스레드를 파라미터의 timeout 시간이 지날 때까지 일시적으로 대기 상태로 전환시킨다.

timeout 시간이 지나거나, notify/notifyAll 호출이 발생하거나, 다른 스레드가 현재 스레드를 인터럽트(interrupt) 할 경우 대기 상태가 하제된다.

 

.wait(long timeout, int nanos)

현재 스레드를 파라미터의 timeout 시간이 지날 때까지 일시적으로 대기 상태로 전환시킨다. int nanos 파라미터로 대기 상태 종료시간을 더욱 세밀하게 설정할 수 있다.

 

 

References

https://inpa.tistory.com/entry/JAVA-%E2%98%95-Object-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%83%81%EC%9C%84-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%9E%AC%EC%A0%95%EC%9D%98-%ED%99%9C%EC%9A%A9-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

☕ 자바 Object 클래스와 메서드 오버라이딩

Object 클래스 모든 자바의 클래스는 Object 클래스로 부터 시작된다. 즉, Object 클래스가 모든 클래스의 조상 혹은 base 라고 할 수 있다. 사실 우리가 클래스 파일을 만들어 클래스명을 작성하면 자

inpa.tistory.com

https://www.tcpschool.com/java/java_api_object

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

https://opentutorials.org/module/516/6241

 

Object 클래스 - Java

상속 자바에서 상속이란 필수적이다. 여러분이 상속하건 하지 않았건 기본적인 상속을 하게 된다. package org.opentutorials.javatutorials.progenitor; class O {} 위의 코드는 아래와 코드가 같다. package org.opent

opentutorials.org

https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

 

Object (Java Platform SE 7 )

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup. The general contract of fi

docs.oracle.com

https://kadosholy.tistory.com/124

 

[Java] 자바 - 스레드 동기화 wait()와 notify(), notifyAll() 사용하기

자바 - 스레드 동기화 wait()와 notify(), notifyAll() 사용하기 멀티스레드 환경에서 동기화를 하더라도 상황에 따라 여러가지 문제점이 있을 수 있습니다. 그중 하나가 제한된 자원에 접근하는 producer-

kadosholy.tistory.com

https://durimongboksil.tistory.com/48

 

java.lang 패키지

java.lang 패키지 java.lang 패키지의 개요 java.lang 패키지는 모든 자바 프로그램에 자동으로 포함되는 패키지입니다. java.lang 패키지에 들어있는 모든 클래스들은 import 선언문을 사용하지 않아도 사

durimongboksil.tistory.com

 

728x90

'Java' 카테고리의 다른 글

[Java] Composition(컴포지션)  (0) 2024.04.09
[Java] 고유 락(Intrinsic Lock)  (0) 2024.04.08
[Java] Thread(스레드)  (1) 2024.04.07
[Java] 가비지 컬렉션(Garbage Collection)  (0) 2024.04.06
[Java] Stream(스트림)  (1) 2024.04.06
  1. Object 클래스란
  2. java.lang 패키지
  3. java.lang.Object
  4. References
'Java' 카테고리의 다른 글
  • [Java] Composition(컴포지션)
  • [Java] 고유 락(Intrinsic Lock)
  • [Java] Thread(스레드)
  • [Java] 가비지 컬렉션(Garbage Collection)
pseudocoder_
pseudocoder_
IE stands for Industrial Engineering, not Internet Explorer ;) 공부한 것을 정리합니다. 가끔 일상도 올려요.
pseudocoder_
코드깎는 IE
pseudocoder_
전체
오늘
어제
  • 분류 전체보기 (54)
    • AI (3)
    • Architecture (1)
    • CS (9)
    • DB (0)
    • Design Pattern (1)
    • Docker (0)
    • Git (0)
    • Java (17)
    • Spring (2)
    • TIL (2)
    • 먹고 자고 개발하는 이야기 (7)
    • 코테 문제 (4)
    • 자료구조 및 알고리즘 (10)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 댓글

hELLO · Designed By 정상우.v4.2.2
pseudocoder_
[Java] Object 클래스
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.