firebase - Firestore 的 `documentSnapshot.toObject(className::class.java)` 如何重新分配在主构造函数中设置的 `val` 值?
问题描述
我一直在开发 Kotlin 后端服务,偶然发现了 FirestoredocumentSnapshot.toObject(className::class.java)
方法。
采取以下 Kotlin data class
:
data class Record(
val firstName: String = "",
val lastName: String = "",
val city: String = "",
val country: String = "",
val email: String = "")
以及我Repository
班上的以下代码:
if (documentSnapshot.exists()) {
return documentSnapshot.toObject(Record::class.java)!!
}
现在,据我了解,该方法documentSnapshot.toObject(className::class.java)
需要并调用无参数默认构造函数,例如val record = Record()
.
此调用将调用主构造函数并将其中规定的默认值(在数据类的情况下为Record
空字符串""
)分配给字段。
然后,它使用公共 setter 方法将实例的字段设置为在document
.
鉴于这些字段已被标记为val
主要数据类构造函数中,这怎么可能?反射在这里起作用吗?在 Kotlin 中val
不是真正的 final吗?
解决方案
Firebase 确实使用反射来设置/获取值。具体来说,它使用 JavaBean 模式来识别属性,然后使用它们的public
getter/setter 或使用public
字段来获取/设置它们。
你data class
被编译成这个 Java 代码的等价物:
public static final class Record {
@NotNull
private final String firstName;
@NotNull
private final String lastName;
@NotNull
private final String city;
@NotNull
private final String country;
@NotNull
private final String email;
@NotNull
public final String getFirstName() { return this.firstName; }
@NotNull
public final String getLastName() { return this.lastName; }
@NotNull
public final String getCity() { return this.city; }
@NotNull
public final String getCountry() { return this.country; }
@NotNull
public final String getEmail() { return this.email; }
public Record(@NotNull String firstName, @NotNull String lastName, @NotNull String city, @NotNull String country, @NotNull String email) {
Intrinsics.checkParameterIsNotNull(firstName, "firstName");
Intrinsics.checkParameterIsNotNull(lastName, "lastName");
Intrinsics.checkParameterIsNotNull(city, "city");
Intrinsics.checkParameterIsNotNull(country, "country");
Intrinsics.checkParameterIsNotNull(email, "email");
super();
this.firstName = firstName;
this.lastName = lastName;
this.city = city;
this.country = country;
this.email = email;
}
...
}
在这种情况下,当我需要将属性值写入数据库时,Firebase 使用公共 getter 来获取属性值,并在从数据库中读取属性值时使用字段来设置属性值。
推荐阅读
- reactjs - 如何在 React 中使用 web3?
- python - 我想使用 openpyxl 模块自动调整 Excel 列宽,但有些数据是公式化的。如何通过 Python 获得真正的价值?
- image - File (string virtualpath, "image/jpeg" ) 找不到我的项目的文件并且在教程中工作得很好
- javascript - 在 owl.carousel.change 上动画 CSS
- java - 导出带有阿拉伯语单词 android 的 CSV 文件
- mysql - EasyPHP mysql模块打开按钮空白页
- r - R:导出一系列可以用方向键翻阅的图
- scala - 在 shell 中运行 Scala 脚本时导入错误
- python - 计算数据框中每列值的订单百分比
- c - 包含的 C 文件中的编译指示