I'm learning Android Jetpack, the following code is from a sample project at https://github.com/android/sunflower.
The GardenPlanting.kt code is to design a table, I'm very strange why the author define the table fields in two position, you see that @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id")
is located the inner of the class.
I think that Code B is easy to understand, right?
GardenPlanting.kt
@Entity(
tableName = "garden_plantings",
foreignKeys = [
ForeignKey(entity = Plant::class, parentColumns = ["id"], childColumns = ["plant_id"])
],
indices = [Index("plant_id")]
)
data class GardenPlanting(
@ColumnInfo(name = "plant_id") val plantId: String,
@ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),
@ColumnInfo(name = "last_watering_date")
val lastWateringDate: Calendar = Calendar.getInstance()
) {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var gardenPlantingId: Long = 0
}
Code B
data class GardenPlanting(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: String,
@ColumnInfo(name = "plant_id") val plantId: String,
@ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),
@ColumnInfo(name = "last_watering_date")
val lastWateringDate: Calendar = Calendar.getInstance()
) {
var gardenPlantingId: Long = 0
}
The declaration of a property inside the data
class constructor is used to :
toString()
, equals()
, hashCode()
, and copy()
So if you want to avoid copying fields with the copy
method then the easy way is to declare the fields inside the body of the class.
Example:
fun main() {
val user = User("Pavneet", "29k+")
user.id = kotlin.random.Random.nextInt(10, 20)
val userCopy = user.copy()
println(userCopy) // id won't be printed 'cuz it's not a part of toString method
userCopy.id = 99
print(userCopy.equals(user)) // true, 'cuz id is not being used by the equals method
//var(name, repo, id) = userCopy // error, User must have a 'component3()' function
var(name, repo) = userCopy
}
data class User(val name: String = "", val repo:String="0"){
var id:Int = 0
}
Advantages:
Note: copy
and component
methods cannot be provided explicitly(inside data class). In example B, gardenPlantingId
is replaced with id
so can be removed.
The answer is very simple:
Because in this sample code, the author wants to show that we can use both @PrimaryKey
and @ColumnInfo
annotation to ANY member inside an entity class, regardless its position (it can be in the inside the constructor or at the outside).
To experiment with this, you can just do exactly what you did on Code B. It is also valid, but in that case, gardenPlantingId
will not have a custom column name because we don't use @ColumnInfo
annotation. Also, it is not necessary to declare @PrimaryKey
outside the constructor (like the given example). You can just declare your the primary key annotation inside the constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With