Kotlin Android에서 데이터 클래스의 빈 생성자를 만드는 방법


195

데이터 클래스에 10 개 이상의 매개 변수가 있으며 빈 생성자로 데이터 클래스를 초기화하고 setter를 사용하여 소수의 매개 변수에 대해서만 값을 설정하고 객체를 서버에 전달하고 싶습니다.

data class Activity(
        var updated_on: String,
        var tags: List<String>,
        var description: String,
        var user_id: List<Int>,
        var status_id: Int,
        var title: String,
        var created_at: String,
        var data: HashMap<*, *>,
        var id: Int,
        var counts: LinkedTreeMap<*, *>,
)

용법:

이와 같은 것은 쉬울 것입니다

                val activity =  Activity();
                activity.title = "New Computer"
                sendToServer(activity)

그러나 생성자를 만드는 동안 모든 인수를 전달해야합니다. 위와 같이 단순화하려면 어떻게해야합니까?

                val activity =  Activity(null,null,null,null,null,"New Computer",null,null,null,null);
                sendToServer(activity)

답변:


245

여기에는 두 가지 옵션이 있습니다.

  1. 기본 생성자 매개 변수에 기본값을 지정하십시오 .

    data class Activity(
        var updated_on: String = "",
        var tags: List<String> = emptyList(),
        var description: String = "",
        var user_id: List<Int> = emptyList(),
        var status_id: Int = -1,
        var title: String = "",
        var created_at: String = "",
        var data: HashMap<*, *> = hashMapOf<Any, Any>(),
        var id: Int = -1,
        var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
    ) 
  2. 매개 변수가없는 보조 생성자 를 선언 하십시오 .

    data class Activity(
        var updated_on: String,
        var tags: List<String>,
        var description: String,
        var user_id: List<Int>,
        var status_id: Int,
        var title: String,
        var created_at: String,
        var data: HashMap<*, *>,
        var id: Int,
        var counts: LinkedTreeMap<*, *>
    ) {
        constructor() : this("", emptyList(), 
                             "", emptyList(), -1, 
                             "", "", hashMapOf<Any, Any>(), 
                             -1, LinkedTreeMap<Any, Any>()
                             )
    }

당신에 의존하지 않는 경우 copy또는 equalsActivity클래스 또는 자동 생성 사용하지 않는 data class전혀 방법을 당신과 같이 일반 클래스를 사용할 수 있습니다 :

class ActivityDto {
    var updated_on: String = "",
    var tags: List<String> = emptyList(),
    var description: String = "",
    var user_id: List<Int> = emptyList(),
    var status_id: Int = -1,
    var title: String = "",
    var created_at: String = "",
    var data: HashMap<*, *> = hashMapOf<Any, Any>(),
    var id: Int = -1,
    var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
}

모든 DTOdata class그 반대 일 필요는 없습니다 . 실제로 내 경험상 데이터 클래스가 복잡한 비즈니스 로직과 관련된 영역에서 특히 유용하다는 것을 알았습니다.


1
감사합니다 @miensol, 복사 재미를 사용하여 수행 할 수있는 방법이 있습니까? 예. kotlinlang.org/docs/reference/data-classes.html#copying
Sai

@SaiKiran을 사용 copy하려면 데이터 클래스 인스턴스가 필요합니다. 그것을 만들려면 생성자를 호출해야하며 여기에 문제가 있습니다.
miensol

Android Studio 2.3에 Kotlin 1.1.2를 사용하고 있으며 emptyList를 사용할 수 없습니다 : /
Gonzalo

신경 쓰지 마. build.gradle 구성 파일에 kotlin을 추가하지 않았습니다.
Gonzalo

3
@Muhammadchhota emptyList는 반복적으로 메모리를 할당하지 않습니다. singleton을 반환합니다 .
miensol

70

모든 필드에 기본값을 지정 하면 Kotlin이 빈 생성자를 자동으로 생성합니다.

data class User(var id: Long = -1,
                var uniqueIdentifier: String? = null)

그리고 당신은 단순히 전화 할 수 있습니다 :

val user = User()

1
ID가 자동 생성되면 어떻게 사용합니까?
Siddhpura Amit

나를 위해 일했다. Firebase 채팅 메시지 :class FeelComChatMessage (messageText: String = "", messageUser: String = "")
Jitendra Surve

14

@miensol 답변과 함께 몇 가지 세부 정보를 추가하겠습니다.

데이터 클래스를 사용하여 Java 표시 가능한 빈 생성자를 원하면 명시 적으로 정의해야합니다.

기본값 + 생성자 지정자를 사용하는 것은 매우 쉽습니다.

data class Activity(
    var updated_on: String = "",
    var tags: List<String> = emptyList(),
    var description: String = "",
    var user_id: List<Int> = emptyList(),
    var status_id: Int = -1,
    var title: String = "",
    var created_at: String = "",
    var data: HashMap<*, *> = hashMapOf<Any, Any>(),
    var id: Int = -1,
    var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
) {
    constructor() : this(title = "") // this constructor is an explicit
                                     // "empty" constructor, as seen by Java.
}

즉,이 트릭을 사용하면 표준 Java 직렬 변환기 (Jackson, Gson 등)를 사용하여이 오브젝트를 직렬화 / 직렬화 할 수 있습니다.


마지막 칭찬이 잘못되었습니다. 적어도 Gson serializer의 경우 실제로 Gson은 안전하지 않은 메커니즘을 사용하여 객체를 만들고 생성자를 호출하지 않습니다. 방금 관련 질문에 답변했습니다 stackoverflow.com/questions/59390294/…
Võ Quang Hòa

6

각 기본 생성자 매개 변수에 기본값을 제공하는 경우 :

data class Item(var id: String = "",
            var title: String = "",
            var condition: String = "",
            var price: String = "",
            var categoryId: String = "",
            var make: String = "",
            var model: String = "",
            var year: String = "",
            var bodyStyle: String = "",
            var detail: String = "",
            var latitude: Double = 0.0,
            var longitude: Double = 0.0,
            var listImages: List<String> = emptyList(),
            var idSeller: String = "")

그리고 인스턴스없이 또는 인수없이 또는 그 순간 가지고있는 인수로 인스턴스를 호출 할 수있는 클래스에서

var newItem = Item()

var newItem2 = Item(title = "exampleTitle",
            condition = "exampleCondition",
            price = "examplePrice",
            categoryId = "exampleCategoryId")

3

기본 생성자를 수정하고 각 매개 변수에 기본값을 추가하는 것이 좋습니다 .

data class Activity(
    var updated_on: String = "",
    var tags: List<String> = emptyList(),
    var description: String = "",
    var user_id: List<Int> = emptyList(),
    var status_id: Int = -1,
    var title: String = "",
    var created_at: String = "",
    var data: HashMap<*, *> = hashMapOf<Any, Any>(),
    var id: Int = -1,
    var counts: LinkedTreeMap<*, *> = LinkedTreeMap<Any, Any>()
)

?다음을 추가하여 값을 nullable로 만들 수도 있습니다 null.

data class Activity(
    var updated_on: String? = null,
    var tags: List<String>? = null,
    var description: String? = null,
    var user_id: List<Int>? = null,
    var status_id: Int? = null,
    var title: String? = null,
    var created_at: String? = null,
    var data: HashMap<*, *>? = null,
    var id: Int? = null,
    var counts: LinkedTreeMap<*, *>? = null
)

일반적으로 nullable 객체를 피하는 것이 좋습니다. 코드를 사용할 필요가없는 방식으로 코드를 작성하십시오. 널 입력 불가능 오브젝트는 Java와 비교하여 Kotlin의 장점 중 하나입니다. 따라서 위의 첫 번째 옵션이 바람직 합니다.

두 옵션 모두 원하는 결과를 제공합니다.

val activity = Activity()
activity.title = "New Computer"
sendToServer(activity)

2

Kotlin의 데이터 클래스에 대한 비어 있지 않은 보조 생성자 :

data class ChemicalElement(var name: String,
                           var symbol: String,
                           var atomicNumber: Int,
                           var atomicWeight: Double,
                           var nobleMetal: Boolean?) {

    constructor(): this("Silver",
                        "Ag", 
                        47,
                        107.8682,
                        true)
}

fun main() {
    var chemicalElement = ChemicalElement()
    println("RESULT: ${chemicalElement.symbol} means ${chemicalElement.name}")
    println(chemicalElement)
}

// RESULT: Ag means Silver
// ChemicalElement(name=Silver, symbol=Ag, atomicNumber=47, atomicWeight=107.8682, nobleMetal=true)

Kotlin의 데이터 클래스에 대한 빈 보조 생성자 :

data class ChemicalElement(var name: String,
                           var symbol: String,
                           var atomicNumber: Int,
                           var atomicWeight: Double,
                           var nobleMetal: Boolean?) {

    constructor(): this("",
                        "", 
                        -1,
                        0.0,
                        null)
}

fun main() {
    var chemicalElement = ChemicalElement()
    println(chemicalElement)
}

// ChemicalElement(name=, symbol=, atomicNumber=-1, atomicWeight=0.0, nobleMetal=null)

2

로부터 문서

참고 : JVM에서 기본 생성자의 모든 매개 변수에 기본값이있는 경우 컴파일러는 기본값을 사용하는 추가 매개 변수없는 생성자를 생성합니다. 이를 통해 매개 변수없는 생성자를 통해 클래스 인스턴스를 작성하는 Jackson 또는 JPA와 같은 라이브러리에서 Kotlin을 쉽게 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.