Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic object in Kotlin

Tags:

kotlin

I was experimenting in some global API-parser (to check net-connection, call API & return formatted data by a single call from source) for Android using Kotlin & at some point I had to create a generic type of object as like the following snippet, when found the compilation error at the 1st line like Type parameters are not allowed for objects:

object RestApiParser<T> // ERROR(mark under T): Type parameters are not allowed for objects
: Callback<T> {

    override fun onFailure(call: Call<T>?, t: Throwable?) {
        // bla-bla-blaa codes ...
    }

    override fun onResponse(call: Call<T>?, response: Response<T>?) {
        // bla-bla-blaa codes ...
    }

    fun getResponse(context: Context, call: Call<T>, callback: RestApiCallback<T>) {
       // bla-bla-blaa codes ...
    }

    fun getList(context: Context, call: Call<ArrayList<T>>, callback: RestApiCallback<T>) {
       // bla-bla-blaa codes ...
    }

    // there are more codes like the above ...
}

I used companion object inside class delivering the same error & then had to continue reverting the RestApiParser to a simple class & calling that through a variable every time, which didn't satisfy our need.

Yes, singleton structure might be coded like the following companion segment using upper-bound:

companion object {
    private var instance: RestApiParser<*>? = null
    fun <T> getParser(): RestApiParser<T> {
        if (instance == null)
            instance = RestApiParser<T>()
        return instance as RestApiParser<T>
    }
}

But it would feel good to create generic object in Kotlin.

Question:
Is there any way to create generic object in Kotlin?
If not, then what may best suit the mentioned scenario?

like image 208
Touhid Avatar asked Feb 26 '18 09:02

Touhid


People also ask

How do you make a generic object in Kotlin?

An object is a singleton. A singleton is something for which only one instance exists. Type parameters allow to specify type arguments for a specific instance of a class, and as such, make sense only when there is more than one instance. Therefore, no, there is no way to create a generic object in Kotlin.

What is a generic object?

Generic objects are structures for storing and interacting with data in an app. They are the primary type of entity through which the engine provides access to the components of an app.

What is generic function in Kotlin?

Generics means we use a class or an implementation in a very generic manner. For example, the interface List allows us for code reuse. We are able to create a list of Strings, of integer values and we will have the same operations even if we have different types.


2 Answers

An object is a singleton. A singleton is something for which only one instance exists. Type parameters allow to specify type arguments for a specific instance of a class, and as such, make sense only when there is more than one instance. Therefore, no, there is no way to create a generic object in Kotlin.

In your RestApiParser example, you can simply specify type parameters for each individual function and leave the object as non-generic. Using an object as a callback for REST API calls sounds like quite poor design to me (because of threading issues, among others), so I'd replace it with creating a new callback instance with proper type arguments for each call.

like image 133
yole Avatar answered Oct 30 '22 22:10

yole


Under a very strict precondition it's possible to generalize the callback implementation. You cannot use the type of the data and you will not be able to access it in any case. So you cannot make a call to Gson or similar utilities for example. All you should ever consider is having a pure Object to use.

object RestApiParser : Callback<Any> {
    override fun onFailure(call: Call<Any>?, t: Throwable?) = Unit

    @Suppress("UNCHECKED_CAST")
    fun <T> asCallback(): Callback<T> = this as Callback<T>
}
like image 31
tynn Avatar answered Oct 30 '22 22:10

tynn