Kotlin

[Kotlin] Data Class

onemask 2020. 4. 28. 00:25

Kotlin Data Class 사용은 자주 했는데, 그 안에 어떤 메서드들이 숨어 있는지 잊고 살았던 것 같다. 

이 번 포스팅으로 정리하고자 한다. 

 

 

Kotlin Data Class 어떻게 나왔음? 

우리는  data를 담기 위하여 자주 data class 를 생성한다.

기존의 Java에서 Class 를 생성해 주기 위해서는 CRUD에 필요한 getter(), setter() 메서드가 필요했다.

그 외에도 여러 메소드가 필요했다. 

public class User {

    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @NotNull
    @Override
    public String toString() {
        return this.getClass().getName() +
                "(name=" + getName() + ", " +
                "age=" + getAge() + ")";
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!User.class.isAssignableFrom(obj.getClass())) {
            return false;
        }

        final User other = (User) obj;
        if ((this.name == null) ?
                (other.name != null) :
                !this.name.equals(other.name)) {
            return false;
        }
        return this.age == other.age;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 53 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 53 * hash + this.age;
        return hash;
    }
}

 

이러한 반복적인 작업이 많고, 버그가 발생하기 쉽기에 코틀린의 data class가 나왔다.  

 


Kotlin Data Class 안에 뭐 들었어? 

Kotlin의 Data class 에는 3가지 메서드가 자동으로 생성된다. 

data class User(
    val name : String,
    var age : Int
)

우선 생성자부터 보자. 

  • val
    immutable 로 내부적으로 getter()가 생성된다.
  • var 
    mutable로 getter()와 setter()가 만들어진다. 

내부적으로 생성되는 3가지 메소드는 아래와 같다. 

 

  •  equls()
  • hashCode()
  • toString() 

어떻게 사용될까? 왜 필요할까? 

위 3가지 메소드구현 할 때, 우리는 객체를 생성하고 field 값이 동일한 두 인스턴스를 교환, 비교할 수 있다. 

각 메소드들 어떻게 사용되는지 살펴보자.

 

1. equls ()

기본적으로 두 변수가 동일한 객체를 참조하는 경우에만 true를 반환한다. 

    val Job = User("Steve Jobs",52)
    val bob = User("Steve bobs",52)

    print("is equals ${Job.equals(bob)}") //false

2. hashCode() 

default 값으로 객체의 메모리 주소를 16진 수로 나타낸다.

    val Job = User("Steve Jobs",52)
    val bob = User("Steve bobs",52)

    print("job hashCode ${Job.hashCode()} bob hashCode ${bob.hashCode()}")
    //job hashCode 1911481297 bob hashCode 1933645801

3. toString()

기본적으로 hashCode를 리턴한지만, 메모리 주소 값을 사람이 읽기 쉽게 보여주는 것이다. 

User@34033bd0+ → User(name=Steve, age=52) .

 


Kotlin Data Class 뭐 할 수 있어?

 

> Destructuring Declarations 가능

    val Job = User("Steve Jobs", 52)
    val bob = User("Steve bobs", 52)
    val (name, age) = Job
    
    println("name $name age $age")
    println("component1 is ${Job.component1()}") //component1 is Steve Jobs
    println("component2 is ${Job.component2()}") //component2 is 52

위와 같이 기존 자료구조를 해체하여 선언하는 것이 가능한 것이다. 

 

> Copy function()  사용 가능

data keyword는 클래스를 복사하여 어떤 속성 값을 바꾸는 것이 손쉽게 가능하다.

    val Job = User("Steve Jobs", 52)
    val JobsToday= Job.copy(age = 63)
    
    println("Job $Job")//Job User(name=Steve Jobs, age=52)
    println("JobsToday ${JobsToday}") //JobsToday User(name=Steve Jobs, age=63)

 

Kotlin Data Class 요구사항 및 제한사항

- 데이터 클래스의 생성자는 적어도 하나의 파라미터각 필요하다.

- 모든 파라미터는 val, var로 표시되어야 한다.

- data class는 abstract, open, seald, inner 클래스가 될 수 없다.

- equls(), toString(), hashCode()는 명시적으로 오버라이드 할 수 있다. 

- componentN(), copy() 함수에 대하여는 명시적으로 구현이 허용되지 않는다.

- data class는 다른 data class를 상속하지 않는다. 

 

 

Reference

 

LIST