web-dev-qa-db-ja.com

Javaインターフェースを実装するKotlinデータクラス

現在のプロジェクトにKotlinを導入しようとしています。私は、データクラスに完全にマップされているように見えるエンティティから始めることにしました。たとえば、データクラスがあります。

data class Video(val id: Long, val ownerId: Long, val title: String, val description: String? = null,
             val imgLink: String? = null, val created: Date? = null, val accessKey: String? = null,
             val views: Long? = null, val comments: Long? = null, val videoLink: String? = null): Entity

Javaインターフェースを実装するもの:

public interface Entity {
   Long getId();  
}

しかし、何らかの理由でコンパイラはメソッドがすでに実装されていることを理解していません:

クラス「Video」は抽象として宣言するか、抽象メンバーを実装する必要がありますpublic abstract fun getId():kotlin.Long! net.alfad.data.Entityで定義

Id paramに追加のキーワードを使用する必要がありますか? 「!」とは署名の意味ですか?

30
Odysseus

ここでの問題は、KotlinがJava class Entityを最初にロードし、getIdをいくつかのプロパティのゲッターとしてではなく、関数として認識することです。プロパティゲッターKotlinクラスでは、関数をオーバーライドできないため、idプロパティはgetId関数の実装としてバインドされません。

これを回避するには、Kotlinクラスの元の関数getIdをオーバーライドする必要があります。これを行うと、新しい関数とバイトコード内のidのゲッター間でJVMシグネチャが競合するため、privateプロパティを作成してコンパイラがゲッターを生成しないようにする必要があります。

data class Video(
    private val id: Long,
    ...
) {
    override fun getId() = id

    ...
}

この回答はここから改作されていることに注意してください https://stackoverflow.com/a/32971284/288456

38

これがデータクラス全体の場合は、getId()をオーバーライドしていません。 idというプロパティがあり、Kotlinがそのためのゲッターを生成するはずですが、抽象関数をオーバーライドしていることを示すためにオーバーライドキーワードでマークされていません。

-編集-アレクサンダーは私を倒しました!彼の答えはとにかく良いです! ;)

1
CaseyB