Post

[Java] Object Class, Immutable Object

[Java] Object Class, Immutable Object

πŸ’‘ 이 κ²Œμ‹œκΈ€μ€ κΉ€μ˜ν•œ κ°•μ‚¬λ‹˜μ˜ μžλ°” κ°•μ˜λ₯Ό μˆ˜κ°•ν•˜λ©° ν•™μŠ΅ν•œ λ‚΄μš©μ„ μ€‘μš”ν•œ ν‚€μ›Œλ“œ μ€‘μ‹¬μœΌλ‘œ μ •λ¦¬ν•œ 개인 ν•™μŠ΅ κΈ°λ‘μž…λ‹ˆλ‹€. 였직 κΈ°μ–΅ 볡기λ₯Ό μœ„ν•œ λͺ©μ μœΌλ‘œ μž‘μ„±λ˜μ—ˆμœΌλ©°, λͺ¨λ“  λ‚΄μš©μ„ ν¬ν•¨ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ ν•™μŠ΅ μžλ£Œλ‘œλŠ” μ ν•©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μž„μ‹œ μ €μž₯본이 λ‚ μ•„κ°€λŠ” κ²½μš°κ°€ μžˆμ–΄ demo둜 μ—…λ‘œλ“œ

Section2 (Object Class)

Object Class

μžλ°”μ—μ„œ λͺ¨λ“  클래슀의 μ΅œμƒμœ„ λΆ€λͺ¨ ν΄λž˜μŠ€λŠ” 항상 Object ν΄λž˜μŠ€μ΄λ‹€.

ν΄λž˜μŠ€μ— 상속 받을 λΆ€λͺ¨ 클래슀λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜λ©΄ Object λ₯Ό 상속 λ°›μ§€ μ•ŠλŠ”λ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
package lang.object;

public class ObjectMain {
    public static void main(String[] args) {
        Child child = new Child();
        child.childMethod();
        child.parentMethod();
        
        // toString()은 Object 클래슀의 λ©”μ„œλ“œ
        String string = child.toString();
        System.out.println(string);
    }
}
  1. child.toString() 을 ν˜ΈμΆœν•œλ‹€.
  2. λ¨Όμ € 본인의 νƒ€μž…μΈ Child μ—μ„œ toString() 을 μ°ΎλŠ”λ‹€. μ—†μœΌλ―€λ‘œ λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ μ˜¬λΌκ°€μ„œ μ°ΎλŠ”λ‹€.
  3. λΆ€λͺ¨ νƒ€μž…μΈ Parent μ—μ„œ μ°ΎλŠ”λ‹€. μ—†μœΌλ―€λ‘œ λΆ€λͺ¨ νƒ€μž…μœΌλ‘œ μ˜¬λΌκ°€μ„œ μ°ΎλŠ”λ‹€.
  4. λΆ€λͺ¨ νƒ€μž…μΈ Object μ—μ„œ μ°ΎλŠ”λ‹€. Object 에 toString() 이 μžˆμœΌλ―€λ‘œ 이 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.

μžλ°”μ—μ„œ λͺ¨λ“  객체의 μ΅œμ’… λΆ€λͺ¨λŠ” Object λ‹€

λͺ¨λ“  ν΄λž˜μŠ€κ°€ Object 클래슀λ₯Ό 상속 λ°›λŠ” μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  • 곡톡 κΈ°λŠ₯ 제곡
  • λ‹€ν˜•μ„±μ˜ κΈ°λ³Έ κ΅¬ν˜„
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package lang.object.poly;

public class ObjectPolyExample1 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Car car = new Car();

        action(dog);
        action(car);
    }

    private static void action(Object obj) {
        // obj.sound(); // 컴파일 였λ₯˜, ObjectλŠ” sound()κ°€ μ—†λ‹€.
        // obj.move(); // 컴파일 였λ₯˜, ObjectλŠ” move()κ°€ μ—†λ‹€.

        // 객체에 λ§žλŠ” λ‹€μš΄μΊμŠ€νŒ… ν•„μš”
        if (obj instanceof Dog dog) {
            dog.sound();
        } else if (obj instanceof Car car) {
            car.move();
        }
    }
}

Object λ°°μ—΄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package lang.object.poly;

public class ObjectPolyExample2 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Car car = new Car();
        Object object = new Object(); // Object μΈμŠ€ν„΄μŠ€λ„ λ§Œλ“€ 수 μžˆλ‹€.

        Object[] objects = {dog, car, object}; // λ‹€μ–‘ν•œ 객체λ₯Ό Object 배열에 μ €μž₯
        size(objects);
    }

    private static void size(Object[] objects) {
        System.out.println("μ „λ‹¬λœ 객체의 μˆ˜λŠ”: " + objects.length);
    }
}

toString()
Object.toString() λ©”μ„œλ“œλŠ” 객체의 정보λ₯Ό λ¬Έμžμ—΄ ν˜•νƒœλ‘œ μ œκ³΅ν•œλ‹€.

Object κ°€ μ œκ³΅ν•˜λŠ” toString() λ©”μ„œλ“œλŠ” 기본적으둜 νŒ¨ν‚€μ§€λ₯Ό ν¬ν•¨ν•œ 객체의 이름과 객체의 μ°Έμ‘°κ°’(ν•΄μ‹œ
μ½”λ“œ)λ₯Ό 16μ§„μˆ˜λ‘œ μ œκ³΅ν•œλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package lang.object.tostring;

public class ToStringMain1 {
    public static void main(String[] args) {
        Object object = new Object();
        String string = object.toString();

        // toString() λ°˜ν™˜κ°’ 좜λ ₯
        System.out.println(string);

        // object 직접 좜λ ₯
        System.out.println(object);
    }
}
1
2
java.lang.Object@a09ee92
java.lang.Object@a09ee92
1
2
3
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

System.out.println() λ©”μ„œλ“œλŠ” 사싀 λ‚΄λΆ€μ—μ„œ toString() 을 ν˜ΈμΆœν•œλ‹€.

Object νƒ€μž…(μžμ‹ 포함)이 println() 에 인수둜 μ „λ‹¬λ˜λ©΄ λ‚΄λΆ€μ—μ„œ obj.toString() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ„œ κ²°κ³Ό
λ₯Ό 좜λ ₯ν•œλ‹€.

toString() μ˜€λ²„λΌμ΄λ”©

Object.toString() λ©”μ„œλ“œκ°€ 클래슀 정보와 참쑰값을 μ œκ³΅ν•˜μ§€λ§Œ 이 μ •λ³΄λ§ŒμœΌλ‘œλŠ” 객체의 μƒνƒœλ₯Ό 적절히 λ‚˜νƒ€λ‚΄μ§€ λͺ»ν•œλ‹€. κ·Έλž˜μ„œ 보톡 toString() 을 μž¬μ •μ˜(μ˜€λ²„λΌμ΄λ”©)ν•΄μ„œ 보닀 μœ μš©ν•œ 정보λ₯Ό μ œκ³΅ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€.

1
2
3
4
5
6
7
@Override
public String toString() {
    return "Dog{" +
            "dogName='" + dogName + '\'' +
            ", age=" + age +
            '}';
}
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
package lang.object.tostring;

public class ToStringMain2 {
    public static void main(String[] args) {
        Car car = new Car("Car1");
        Dog dog1 = new Dog("Dog1", 5);
        Dog dog2 = new Dog("Dog2", 10);

        System.out.println(car.toString());
        System.out.println(dog1.toString());
        System.out.println(dog2.toString());

        System.out.println(car);
        System.out.println(dog1);
        System.out.println(dog2);

        ObjectPrinter.print(car);
        ObjectPrinter.print(dog1);
        ObjectPrinter.print(dog2);

        String refValue1 = Integer.toHexString(System.identityHashCode(dog1));
        System.out.println(refValue1);
        String refValue2 = Integer.toHexString(System.identityHashCode(dog2));
        System.out.println(refValue2);
    }
}

1
2
3
4
5
6
7
8
9
10
11
lang.object.tostring.Car@5f184fc6
Dog{dogName='Dog1', age=5}
Dog{dogName='Dog2', age=10}
lang.object.tostring.Car@5f184fc6
Dog{dogName='Dog1', age=5}
Dog{dogName='Dog2', age=10}
객체 정보 좜λ ₯: lang.object.tostring.Car@5f184fc6
객체 정보 좜λ ₯: Dog{dogName='Dog1', age=5}
객체 정보 좜λ ₯: Dog{dogName='Dog2', age=10}
506e1b77
4fca772d

Object와 OCP

ꡬ체적인 것에 의쑴 Β«< 좔상적인 것에 μ˜μ‘΄πŸ‘

1
2
3
4
5
6
public class ObjectPrinter {
    public static void print(Object obj) {
        String string = "객체 정보 좜λ ₯: " + obj.toString();
        System.out.println(string);
    }
}

equals() - 동일성과 동등성

동일성(Identity): ==μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•΄μ„œ 두 객체의 μ°Έμ‘°κ°€ λ™μΌν•œ 객체λ₯Ό 가리킀고 μžˆλŠ”μ§€ 확인
동등성(Equality): equals() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 두 객체가 λ…Όλ¦¬μ μœΌλ‘œ λ™λ“±ν•œμ§€ 확인

1
2
3
4
5
6
7
8
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserV2 userV2 = (UserV2) o;
        return Objects.equals(id, userV2.id);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package lang.object.equals;

public class EqualsMainV2 {
    public static void main(String[] args) {
        UserV2 user1 = new UserV2("id-100");
        UserV2 user2 = new UserV2("id-100");

        System.out.println("identity " + (user1 == user2));
        System.out.println("equality " + user1.equals(user2));
    }
}

//identity false
//equality true

Section3 (Immutable Object)

Side Effect참쑰값을 λ‹€λ₯Έ λ³€μˆ˜μ— λŒ€μž…ν•˜λŠ” μˆœκ°„ μ—¬λŸ¬ λ³€μˆ˜κ°€ ν•˜λ‚˜μ˜ 객체λ₯Ό κ³΅μœ ν•˜κ²Œ λœλ‹€. μ‰½κ²Œ μ΄μ•ΌκΈ°ν•΄μ„œ 객체의 곡유λ₯Ό λ§‰μ„μˆ˜ μžˆλŠ” 방법이 μ—†λ‹€.

λΆˆλ³€μ΄λΌλŠ” λ‹¨μˆœν•œ μ œμ•½μ„ μ‚¬μš©ν•΄μ„œ μ‚¬μ΄λ“œ μ΄νŽ™νŠΈλΌλŠ” 큰 문제λ₯Ό 막을 수 μžˆλ‹€.

객체의 곡유 μ°Έμ‘°λŠ” 막을 수 μ—†λ‹€. κ·Έλž˜μ„œ 객체의 값을 λ³€κ²½ν•˜λ©΄ λ‹€λ₯Έ κ³³μ—μ„œ μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜μ˜ 값도 ν•¨κ»˜ λ³€κ²½λ˜λŠ” μ‚¬μ΄λ“œ μ΄νŽ™νŠΈκ°€ λ°œμƒν•œλ‹€.

μ‚¬μ΄λ“œ μ΄νŽ™νŠΈκ°€ λ°œμƒν•˜λ©΄ μ•ˆλ˜λŠ” 상황이라면 λΆˆλ³€ 객체λ₯Ό λ§Œλ“€μ–΄μ„œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

λΆˆλ³€ κ°μ²΄λŠ” 값을 λ³€κ²½ν•  수 μ—†κΈ° λ•Œλ¬Έμ— μ‚¬μ΄λ“œ μ΄νŽ™νŠΈκ°€ μ›μ²œ μ°¨λ‹¨λœλ‹€.

This post is licensed under CC BY 4.0 by the author.