Here is the problem I am trying to resolve, I am trying to use a void type as a generic type:
class Parent {
private abstract class Item<out T>(val data: T)
// This subclass should contain data
private class ItemContent(val data: String): Item<String>(data)
// This subclass doesn't contain data
private class ItemNoContent: Item<Any?>(null)
}
Some base classes like ItemNoContent doesn't contain meaningful data so I make ItemNoContent extends Item(null). It works but I feel that the use of Any? and null is inappropriate here. Is there a more Kotlin way to solve this optional generic problem?
To make a generic type optional, you have to assign the void as the default value. In the example below, even though the function takes a generic type T, still you can call this function without passing the generic type and it takes void as default.
We can make generic variable using this kind of syntax: "val destinationActivity: Class<*>". Main part is "*".
Kotlin generic example When we call the generic method <T>printValue(list: ArrayList<T>) using printValue(stringList), the type T of method <T>printValue(list: ArrayList<T>)will be replaced by String type.
Type Erasure. As with Java, Kotlin's generics are erased at runtime. That is, an instance of a generic class doesn't preserve its type parameters at runtime. For example, if we create a Set<String> and put a few strings into it, at runtime we're only able to see it as a Set.
You can also use Item<Unit>(Unit)
which represents a void
value in Kotlin.
Some base classes like ItemNoContent doesn't contain meaningful data
Then why extend a class which is supposed to have it? While Unit
and null
are both options, consider also
private abstract class Item<out T>
private abstract class ItemWithContent<out T>(val data: T) : Item<T>
...
// object may make more sense than class here
private object ItemNoContent : Item<Nothing>()
I would tweak the inheritance like this:
abstract class Item
abstract class ItemWithContent<T>(val d: T): Item()
class ItemWithStringContent(d: String): ItemWithContent<String>(d)
class ItemWithNoContent: Item()
This way, there is not need to use Unit
or Nothing
.
Usage:
fun main(args: Array<String>){
val t: Item = ItemWithStringContent("test")
println((t as? ItemWithStringContent)?.d)
}
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