Kotlin Androidでデータクラスの空のコンストラクターを作成する方法


195

データクラスに10個以上のパラメーターがあります。空のコンストラクターでデータクラスを初期化し、セッターを使用していくつかのパラメーターの値のみを設定し、オブジェクトをサーバーに渡します。

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

ここには2つのオプションがあります。

  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. パラメーターのない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>()
}

すべてのDTOがaである必要はなくdata class、その逆も同様です。実際、私の経験では、データクラスは、いくつかの複雑なビジネスロジックを含む領域で特に有用であることがわかりました。


1
@miensolに感謝します。copyfunを使用してこれを行う方法はありますか。例えば。kotlinlang.org/docs/reference/data-classes.html#copying
Sai

@SaiKiranを使用copyするには、データクラスインスタンスが必要です。それを作成するには、コンストラクタを呼び出す必要があります-そして、これが問題でした。
miensol 2016年

私はKotlin 1.1.2 for Android Studio 2.3を使用していますが、emptyListは利用できません:/
Gonzalo

気にしないで。build.gradle設定ファイルにkotlinを追加していません。
ゴンザロ2017年

3
@Muhammadchhota emptyListは繰り返しメモリを割り当てません。シングルトンを返します
miensol 2017年

70

あなたが与える場合はすべてのフィールドにデフォルト値を -空のコンストラクタはKotlinによって自動的に生成されます。

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

そしてあなたは単に呼び出すことができます:

val user = User()

1
idが自動生成された場合、どのように使用しますか?
Siddhpura Amit

私のために働いた。Firebase Chatメッセージの場合: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シリアライザーの場合、実際、Gsonは安全でないメカニズムを使用してオブジェクトを作成し、コンストラクターを呼び出しません。ここで関連する質問に答えました。stackoverflow.com
…–VõQuangHòaDec

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>()
)

追加して値をヌル可能にして?から、次のようにアッシングすることもできます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
)

一般に、null許容オブジェクトを回避することをお勧めします-それらを使用する必要がない方法でコードを記述します。nullにできないオブジェクトは、Javaと比較したKotlinの利点の1つです。したがって、上記の最初のオプションが推奨されます。

どちらのオプションでも、望ましい結果が得られます。

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.