Kotlin 中 Data Class 中的私有成员变量
Private members variables in Data Class in Kotlin
我是 kotlin 的新手,当我阅读 kotlin 中的数据 classes 时,我发现这些 code.Its 基本上是 java 模型 class 和 kotlin 数据 class 并且在那儿写了两个代码执行相同的任务。
代码 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;
}}
代码 2
data class VideoGame(val name: String, val publisher: String, var reviewScore: Int)
我的问题是 在数据 class 中,所有变量都是 public 而不是私有的,任何人都可以借助此对象直接访问变量class 但在 java 代码中所有变量都是私有的,这就是为什么我们必须为这些成员变量编写 getter 和 setter 如果它是 public不需要 getter 和 setter.So 这些代码如何相同?
data class
的主要用途是方便写POJOs.
如果你进入 IDE 并写下你的 VideoGame
class:
data class VideoGame(val name: String, val publisher: String, var reviewScore: Int)
然后反编译:
Your IDE Toolbar > Tools > Kotlin > Show Kotlin bytecode > Decompile
你明白了:
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 1,
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¢\u0006\u0002\u0010\u0007J\t\u0010\u000f\u001a\u00020\u0003HÆ\u0003J\t\u0010\u0010\u001a\u00020\u0003HÆ\u0003J\t\u0010\u0011\u001a\u00020\u0006HÆ\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Æ\u0001J\u0013\u0010\u0013\u001a\u00020\u00142\b\u0010\u0015\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0016\u001a\u00020\u0006HÖ\u0001J\t\u0010\u0017\u001a\u00020\u0003HÖ\u0001R\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\b\u0010\tR\u0011\u0010\u0004\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\n\u0010\tR\u001a\u0010\u0005\u001a\u00020\u0006X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u000b\u0010\f\"\u0004\b\r\u0010\u000e¨\u0006\u0018"},
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"}
)
public final class VideoGame {
@NotNull
private final String name;
@NotNull
private final String publisher;
private int reviewScore;
@NotNull
public final String getName() {
return this.name;
}
@NotNull
public final String getPublisher() {
return this.publisher;
}
public final int getReviewScore() {
return this.reviewScore;
}
public final void setReviewScore(int var1) {
this.reviewScore = var1;
}
public VideoGame(@NotNull String name, @NotNull String publisher, int reviewScore) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(publisher, "publisher");
super();
this.name = name;
this.publisher = publisher;
this.reviewScore = reviewScore;
}
@NotNull
public final String component1() {
return this.name;
}
@NotNull
public final String component2() {
return this.publisher;
}
public final int component3() {
return this.reviewScore;
}
@NotNull
public final VideoGame copy(@NotNull String name, @NotNull String publisher, int reviewScore) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(publisher, "publisher");
return new VideoGame(name, publisher, reviewScore);
}
// $FF: synthetic method
public static VideoGame copy$default(VideoGame var0, String var1, String var2, int var3, int var4, Object var5) {
if ((var4 & 1) != 0) {
var1 = var0.name;
}
if ((var4 & 2) != 0) {
var2 = var0.publisher;
}
if ((var4 & 4) != 0) {
var3 = var0.reviewScore;
}
return var0.copy(var1, var2, var3);
}
@NotNull
public String toString() {
return "VideoGame(name=" + this.name + ", publisher=" + this.publisher + ", reviewScore=" + this.reviewScore + ")";
}
public int hashCode() {
String var10000 = this.name;
int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;
String var10001 = this.publisher;
return (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31 + this.reviewScore;
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof VideoGame) {
VideoGame var2 = (VideoGame)var1;
if (Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.publisher, var2.publisher) && this.reviewScore == var2.reviewScore) {
return true;
}
}
return false;
} else {
return true;
}
}
}
所以支持字段是私有的。 Kotlin 正在为您完成所有繁琐而繁重的工作。即:
- 支持字段 getters 和 setters
toString
的基本实现
- 实施
equals
- 实施
hashCode
- 注释为空性
- 编写构造函数实现
- 添加一个有用的
copy
方法
你会得到多达 82 行臃肿的代码,你可能会在 Java 中自己编写这些代码(也许会在其中添加一些错误?)以换取 1 个关键字。是不是很棒?
如此快速回顾
data class
使编写 POJO 变得更容易
val
告诉编译器为给定的 属性 实现 getter。 属性 在 class 本身内也是不可变的。 (您不能在属于该 class 的函数中更改它)
var
告诉编译器提供 setter 和 getters
- 您可以在
data class
中设置属性的可见性,例如:data class MyClass(private val prop: Int)
更多示例:
您在 val 和 var 前面使用的关键字只会影响 getter 和 setter 的可见性。
例如:Public得到但私有集:
class VideoGame {
var pegiRating: Int = 0
private set
}
它们不执行相同的任务,因为 Java 版本有 getter 而 Kotlin 版本没有,因为属性是 val
而不是 var
。如果它们是 var
,那么功能就会全部存在(加上 Kotlin 数据 classes 也有 copy
功能和 equals
、hashcode
和 toString
为您实现)。
默认情况下(没有自定义 getter/setter),Kotlin 属性(public 或不)就像一个 Java 私有字段(public 或不)getters and/or setters。
在Java中,通常不建议将您的字段设置为public,这样其他对象就可以直接修改它们。它不是面向未来的,因为如果您决定在更改值时产生副作用,则必须将字段更改为私有并添加 setter。这会破坏任何与 class 一起工作的代码。为避免这种情况,字段应该是私有的,getter 和 setters 可以是 public,不幸的是,这是很多样板代码。
在 Kotlin 中,您可以将默认 属性 更改为自定义 setter,并且不会破坏使用它的代码。
我是 kotlin 的新手,当我阅读 kotlin 中的数据 classes 时,我发现这些 code.Its 基本上是 java 模型 class 和 kotlin 数据 class 并且在那儿写了两个代码执行相同的任务。
代码 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;
}}
代码 2
data class VideoGame(val name: String, val publisher: String, var reviewScore: Int)
我的问题是 在数据 class 中,所有变量都是 public 而不是私有的,任何人都可以借助此对象直接访问变量class 但在 java 代码中所有变量都是私有的,这就是为什么我们必须为这些成员变量编写 getter 和 setter 如果它是 public不需要 getter 和 setter.So 这些代码如何相同?
data class
的主要用途是方便写POJOs.
如果你进入 IDE 并写下你的 VideoGame
class:
data class VideoGame(val name: String, val publisher: String, var reviewScore: Int)
然后反编译:
Your IDE Toolbar > Tools > Kotlin > Show Kotlin bytecode > Decompile
你明白了:
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 1,
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¢\u0006\u0002\u0010\u0007J\t\u0010\u000f\u001a\u00020\u0003HÆ\u0003J\t\u0010\u0010\u001a\u00020\u0003HÆ\u0003J\t\u0010\u0011\u001a\u00020\u0006HÆ\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Æ\u0001J\u0013\u0010\u0013\u001a\u00020\u00142\b\u0010\u0015\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0016\u001a\u00020\u0006HÖ\u0001J\t\u0010\u0017\u001a\u00020\u0003HÖ\u0001R\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\b\u0010\tR\u0011\u0010\u0004\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\n\u0010\tR\u001a\u0010\u0005\u001a\u00020\u0006X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u000b\u0010\f\"\u0004\b\r\u0010\u000e¨\u0006\u0018"},
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"}
)
public final class VideoGame {
@NotNull
private final String name;
@NotNull
private final String publisher;
private int reviewScore;
@NotNull
public final String getName() {
return this.name;
}
@NotNull
public final String getPublisher() {
return this.publisher;
}
public final int getReviewScore() {
return this.reviewScore;
}
public final void setReviewScore(int var1) {
this.reviewScore = var1;
}
public VideoGame(@NotNull String name, @NotNull String publisher, int reviewScore) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(publisher, "publisher");
super();
this.name = name;
this.publisher = publisher;
this.reviewScore = reviewScore;
}
@NotNull
public final String component1() {
return this.name;
}
@NotNull
public final String component2() {
return this.publisher;
}
public final int component3() {
return this.reviewScore;
}
@NotNull
public final VideoGame copy(@NotNull String name, @NotNull String publisher, int reviewScore) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(publisher, "publisher");
return new VideoGame(name, publisher, reviewScore);
}
// $FF: synthetic method
public static VideoGame copy$default(VideoGame var0, String var1, String var2, int var3, int var4, Object var5) {
if ((var4 & 1) != 0) {
var1 = var0.name;
}
if ((var4 & 2) != 0) {
var2 = var0.publisher;
}
if ((var4 & 4) != 0) {
var3 = var0.reviewScore;
}
return var0.copy(var1, var2, var3);
}
@NotNull
public String toString() {
return "VideoGame(name=" + this.name + ", publisher=" + this.publisher + ", reviewScore=" + this.reviewScore + ")";
}
public int hashCode() {
String var10000 = this.name;
int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;
String var10001 = this.publisher;
return (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31 + this.reviewScore;
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof VideoGame) {
VideoGame var2 = (VideoGame)var1;
if (Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.publisher, var2.publisher) && this.reviewScore == var2.reviewScore) {
return true;
}
}
return false;
} else {
return true;
}
}
}
所以支持字段是私有的。 Kotlin 正在为您完成所有繁琐而繁重的工作。即:
- 支持字段 getters 和 setters
toString
的基本实现
- 实施
equals
- 实施
hashCode
- 注释为空性
- 编写构造函数实现
- 添加一个有用的
copy
方法
你会得到多达 82 行臃肿的代码,你可能会在 Java 中自己编写这些代码(也许会在其中添加一些错误?)以换取 1 个关键字。是不是很棒?
如此快速回顾
data class
使编写 POJO 变得更容易val
告诉编译器为给定的 属性 实现 getter。 属性 在 class 本身内也是不可变的。 (您不能在属于该 class 的函数中更改它)var
告诉编译器提供 setter 和 getters- 您可以在
data class
中设置属性的可见性,例如:data class MyClass(private val prop: Int)
更多示例:
您在 val 和 var 前面使用的关键字只会影响 getter 和 setter 的可见性。
例如:Public得到但私有集:
class VideoGame {
var pegiRating: Int = 0
private set
}
它们不执行相同的任务,因为 Java 版本有 getter 而 Kotlin 版本没有,因为属性是 val
而不是 var
。如果它们是 var
,那么功能就会全部存在(加上 Kotlin 数据 classes 也有 copy
功能和 equals
、hashcode
和 toString
为您实现)。
默认情况下(没有自定义 getter/setter),Kotlin 属性(public 或不)就像一个 Java 私有字段(public 或不)getters and/or setters。
在Java中,通常不建议将您的字段设置为public,这样其他对象就可以直接修改它们。它不是面向未来的,因为如果您决定在更改值时产生副作用,则必须将字段更改为私有并添加 setter。这会破坏任何与 class 一起工作的代码。为避免这种情况,字段应该是私有的,getter 和 setters 可以是 public,不幸的是,这是很多样板代码。
在 Kotlin 中,您可以将默认 属性 更改为自定义 setter,并且不会破坏使用它的代码。