How to use generics in companion object

Companion object is shared

Generic type parameters of the class are not allowed inside the companion objects. The reason is that a single companion object is shared across all the instances of that class. This is true also for the different parameterized types of the same class. So, for example, the companion object is the same for whether it is a Foo<String> or a Foo<Int>. In other words, the T of the enclosing class cannot take different forms String or Int inside the companion object.

The type parameters can only be used with the member functions and member properties of the class.


Closest possible solution

You can define a separate type parameter for the function inside the companion object:

class Foo<T> {
    /* ... */
    companion object {
        fun <T> foo(args: List<T>) {
            /* ... */
        }
    }
}

The T of Foo and T of foo() are independent in this case and need to be instantiated separately:

val instance = Foo<String>()
Foo.foo(listOf<String>())

That's it! Hope that helps understanding the concept.


You either need to declare the generic like so

fun <T> foo(args: List<T>) { ... }

or, if you don't care about the type, you can use a star projection

fun foo(args: List<*>) { ... }