This should do the trick as well. Since the specific concrete class is now available to the compiler it sidesteps the issues @akurczak pointed to. If the List however contains polymorphic objects which are subtypes of Recipient
then the TypeAdapter imo is actually the appropriate way to go since it allows the serialiser to inject the type information into the output stream so that it can then be deserialised correctly when going the opposite direction. (am actually a little miffed at the Java behaviour because roundtrip would mean important type information would be lost and I wonder if that would even be feasible in some circumstances like the one you have where the base type is an interface which doesn’t have a constructor)
import com.google.gson.Gson
interface Subscription<T: Recipient> {
val name: String
val recipients: List<T>
}
interface Recipient {
val email: String
}
data class SubscriptionImpl(override val name: String) : Subscription<RecipientImpl> {
// Works if I change field type to `List<RecipientImpl>`
override var recipients: List<RecipientImpl> = listOf()
}
data class RecipientImpl(override val email: String) : Recipient
fun main() {
val subscription = SubscriptionImpl("A").apply {
recipients = listOf(RecipientImpl("a@b"), RecipientImpl("c@d"))
}
println(Gson().toJson(listOf(subscription)))
}