I'm using data classes in Kotlin to significantly reduce the amount of Java code I would otherwise have to write.
However, in one of my Java classes, I'm not sure what to do to achieve the same result in Kotlin.
My Java class looks a bit like this:
public class DataObject {
private int mId;
private String mName;
public DataObject(int id, String name) {
mId = id;
mName = name;
}
public DataObject(Context context, int id) {
mId = id;
Cursor cursor = ...
cursor.moveToFirst();
mName = cursor.getString(...);
cursor.close();
}
public int getId() {
return mId;
}
public String getName() {
return mName;
}
}
I've tried to rewrite it in Kotlin, and so far I have this:
data class DataObject(val id: Int, val name: String) {
constructor(context: Context, id: Int) : this(id, fetchName(context))
private fun fetchName(context: Context): String {
val cursor = ...
cursor.moveToFirst()
val name = cursor.getString(...)
cursor.close()
return name
}
}
But my IDE (Android Studio) is underlining the part where I call fetchName(context)
in my constructor
in red. It displays the following message:
Cannot access
fetchName
before superclass constructor has been called
How should I resolve this issue?
You can only use member functions on a fully constructed objects. One way to work around that is to use private extension function or simply a function to fetch name:
private fun Context.fetchName(): String {
///...
return cursor.getString(1)
}
data class DataObject(val id: Int, val name: String) {
constructor(context: Context, id: Int) : this(id, context.fetchName())
}
Although I do think that using Cursor
is a bit too heavy job for constructor
. I'd use separate Factory
like so:
data class DataObject(val id: Int, val name: String) {
object FromCursorFactory {
fun create(id: Int, context: Context): DataObject {
val name = context.fetchName()
return DataObject(id, name)
}
}
}
Further reading: