Kotlin 数据类中的私有成员变量

Abh*_*wal 5 java android kotlin kotlin-android-extensions

我是 kotlin 的新手,当我阅读 kotlin 中的数据类时,我发现了这些代码。它基本上是 java 模型类和 kotlin 数据类之间的比较,并且写在那里,两个代码都执行相同的任务。

代码1

public class VideoGame {

private String name;
private String publisher;
private int reviewScore;

public VideoGame(String name, String publisher, int reviewScore) {
    this.name = name;
    this.publisher = publisher;
    this.reviewScore = reviewScore;
}

public String getName() {
    return name;
}

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

public String getPublisher() {
    return publisher;
}

public void setPublisher(String publisher) {
    this.publisher = publisher;
}

public int getReviewScore() {
    return reviewScore;
}

public void setReviewScore(int reviewScore) {
    this.reviewScore = reviewScore;
}}
Run Code Online (Sandbox Code Playgroud)

代码2

data class VideoGame(val name: String, val publisher: String, var reviewScore: Int)
Run Code Online (Sandbox Code Playgroud)

我的问题是,在数据类中,所有变量都是公共的,而不是私有的,任何人都可以借助此类的对象直接访问该变量,但在java代码中,所有变量都是私有的,这就是为什么我们必须编写这些成员变量的getter和setter如果是public的话就不需要getter和setter。那么这些代码是如何相同的呢?

Som*_*boy 15

主要用途是简化POJOdata class的编写工作。

\n\n

如果您进入 IDE 并编写您的VideoGame类:

\n\n
data class VideoGame(val name: String, val publisher: String, var reviewScore: Int)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后反编译它:

\n\n
\n

您的 IDE 工具栏 > 工具 > Kotlin > 显示 Kotlin 字节码 > 反编译

\n
\n\n

你得到这个:

\n\n
@Metadata(\n   mv = {1, 1, 16},\n   bv = {1, 0, 3},\n   k = 1,\n   d1 = {"\\u0000\\"\\n\\u0002\\u0018\\u0002\\n\\u0002\\u0010\\u0000\\n\\u0000\\n\\u0002\\u0010\\u000e\\n\\u0002\\b\\u0002\\n\\u0002\\u0010\\b\\n\\u0002\\b\\r\\n\\u0002\\u0010\\u000b\\n\\u0002\\b\\u0004\\b\\u0086\\b\\u0018\\u00002\\u00020\\u0001B\\u001d\\u0012\\u0006\\u0010\\u0002\\u001a\\u00020\\u0003\\u0012\\u0006\\u0010\\u0004\\u001a\\u00020\\u0003\\u0012\\u0006\\u0010\\u0005\\u001a\\u00020\\u0006\xc2\xa2\\u0006\\u0002\\u0010\\u0007J\\t\\u0010\\u000f\\u001a\\u00020\\u0003H\xc3\x86\\u0003J\\t\\u0010\\u0010\\u001a\\u00020\\u0003H\xc3\x86\\u0003J\\t\\u0010\\u0011\\u001a\\u00020\\u0006H\xc3\x86\\u0003J\'\\u0010\\u0012\\u001a\\u00020\\u00002\\b\\b\\u0002\\u0010\\u0002\\u001a\\u00020\\u00032\\b\\b\\u0002\\u0010\\u0004\\u001a\\u00020\\u00032\\b\\b\\u0002\\u0010\\u0005\\u001a\\u00020\\u0006H\xc3\x86\\u0001J\\u0013\\u0010\\u0013\\u001a\\u00020\\u00142\\b\\u0010\\u0015\\u001a\\u0004\\u0018\\u00010\\u0001H\xc3\x96\\u0003J\\t\\u0010\\u0016\\u001a\\u00020\\u0006H\xc3\x96\\u0001J\\t\\u0010\\u0017\\u001a\\u00020\\u0003H\xc3\x96\\u0001R\\u0011\\u0010\\u0002\\u001a\\u00020\\u0003\xc2\xa2\\u0006\\b\\n\\u0000\\u001a\\u0004\\b\\b\\u0010\\tR\\u0011\\u0010\\u0004\\u001a\\u00020\\u0003\xc2\xa2\\u0006\\b\\n\\u0000\\u001a\\u0004\\b\\n\\u0010\\tR\\u001a\\u0010\\u0005\\u001a\\u00020\\u0006X\\u0086\\u000e\xc2\xa2\\u0006\\u000e\\n\\u0000\\u001a\\u0004\\b\\u000b\\u0010\\f\\"\\u0004\\b\\r\\u0010\\u000e\xc2\xa8\\u0006\\u0018"},\n   d2 = {"Lcom/yourpackage/VideoGame;", "", "name", "", "publisher", "reviewScore", "", "(Ljava/lang/String;Ljava/lang/String;I)V", "getName", "()Ljava/lang/String;", "getPublisher", "getReviewScore", "()I", "setReviewScore", "(I)V", "component1", "component2", "component3", "copy", "equals", "", "other", "hashCode", "toString", "app"}\n)\npublic final class VideoGame {\n   @NotNull\n   private final String name;\n   @NotNull\n   private final String publisher;\n   private int reviewScore;\n\n   @NotNull\n   public final String getName() {\n      return this.name;\n   }\n\n   @NotNull\n   public final String getPublisher() {\n      return this.publisher;\n   }\n\n   public final int getReviewScore() {\n      return this.reviewScore;\n   }\n\n   public final void setReviewScore(int var1) {\n      this.reviewScore = var1;\n   }\n\n   public VideoGame(@NotNull String name, @NotNull String publisher, int reviewScore) {\n      Intrinsics.checkParameterIsNotNull(name, "name");\n      Intrinsics.checkParameterIsNotNull(publisher, "publisher");\n      super();\n      this.name = name;\n      this.publisher = publisher;\n      this.reviewScore = reviewScore;\n   }\n\n   @NotNull\n   public final String component1() {\n      return this.name;\n   }\n\n   @NotNull\n   public final String component2() {\n      return this.publisher;\n   }\n\n   public final int component3() {\n      return this.reviewScore;\n   }\n\n   @NotNull\n   public final VideoGame copy(@NotNull String name, @NotNull String publisher, int reviewScore) {\n      Intrinsics.checkParameterIsNotNull(name, "name");\n      Intrinsics.checkParameterIsNotNull(publisher, "publisher");\n      return new VideoGame(name, publisher, reviewScore);\n   }\n\n   // $FF: synthetic method\n   public static VideoGame copy$default(VideoGame var0, String var1, String var2, int var3, int var4, Object var5) {\n      if ((var4 & 1) != 0) {\n         var1 = var0.name;\n      }\n\n      if ((var4 & 2) != 0) {\n         var2 = var0.publisher;\n      }\n\n      if ((var4 & 4) != 0) {\n         var3 = var0.reviewScore;\n      }\n\n      return var0.copy(var1, var2, var3);\n   }\n\n   @NotNull\n   public String toString() {\n      return "VideoGame(name=" + this.name + ", publisher=" + this.publisher + ", reviewScore=" + this.reviewScore + ")";\n   }\n\n   public int hashCode() {\n      String var10000 = this.name;\n      int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;\n      String var10001 = this.publisher;\n      return (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31 + this.reviewScore;\n   }\n\n   public boolean equals(@Nullable Object var1) {\n      if (this != var1) {\n         if (var1 instanceof VideoGame) {\n            VideoGame var2 = (VideoGame)var1;\n            if (Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.publisher, var2.publisher) && this.reviewScore == var2.reviewScore) {\n               return true;\n            }\n         }\n\n         return false;\n      } else {\n         return true;\n      }\n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以支持字段是私有的。Kotlin 正在为您完成所有繁琐而繁重的工作。那是:

\n\n
    \n
  1. 使用 getter 和 setter 支持字段
  2. \n
  3. 基本实现toString
  4. \n
  5. 实施equals
  6. \n
  7. 实施hashCode
  8. \n
  9. 注释可空性
  10. \n
  11. 编写构造函数实现
  12. \n
  13. 添加一个有用的copy方法
  14. \n
\n\n

您会得到 82 行臃肿的代码,这些代码可能是您自己用 Java 编写的(也许其中存在一些错误?),以换取 1 个关键字。是不是很厉害呢?

\n\n

这么快回顾一下

\n\n
    \n
  • data class让编写 POJO 变得更容易
  • \n
  • val告诉编译器为给定的属性实现 getter。该属性在类本身内也是不可变的。(您无法在属于该类的函数中更改它)
  • \n
  • var告诉编译器提供 setter 和 getter
  • \n
  • 您可以设置属性的可见性,如下所示data classdata class MyClass(private val prop: Int)
  • \n
\n\n

更多示例:

\n\n

在 val 和 var 前面使用的关键字只会影响 getter 和 setter 的可见性。

\n\n

例如:公共获取但私有设置:

\n\n
class VideoGame {\n      var pegiRating: Int = 0\n           private set\n}\n
Run Code Online (Sandbox Code Playgroud)\n