J_Strauton
J_Strauton

Reputation: 2418

How to create an instance of a class by passing the type

I want to be able to say make an instance of this class and give a type then the code can instantiate a new instance of that class.

fun maker(type: Class<Animal>): Animal {
    if(type == Class<Dog>) {
       return Dog()
    } 
    else if (type == Class<Cat>) {}
    ...
}

What is a good way to do this?

Upvotes: 0

Views: 558

Answers (4)

m.antkowicz
m.antkowicz

Reputation: 13571

If the function can be inline you can also use reified type

inline fun<reified T: Animal> make() = T::class.createInstance()

...

val dog = make<Dog>()

Please notice that to use createInstance() the class must have no-arg constructor or IllegalArgumentException will be thrown

Upvotes: 0

Nitesh Sharma
Nitesh Sharma

Reputation: 555

(Updated) I am not an expert in Kotlin but you can do something like this :

import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance

class A {
    fun greet() {
        println("Hello A");
    }
}

class B{
    fun greet() {
        println("Hello B");
    }
}

fun <T : Any> maker(clazz: KClass<T>): T {
    return clazz.createInstance();
}

val aObj = maker<A>(A::class);
aObj.greet();

val bObj = maker<B>(B::class);
bObj.greet();

Output:

Hello A
Hello B

I hope now it makes sense you just need to pass the class to the method and it returns an object.

As you will be using Animal as a parent class so you can replace Any => Animal

fun <T : Animal> maker(clazz: KClass<T>): T {
    return clazz.createInstance();
}

Upvotes: 0

Tenfour04
Tenfour04

Reputation: 93561

If they all have zero-argument constructors, you can do:

fun maker(type: Class<Animal>): Animal {
    return type.newInstance()
}

You can make it return the type that was passed in for a little more versatility:

fun <T: Animal> maker(type: Class<T>): T {
    return type.newInstance()
}

Upvotes: 2

chef417
chef417

Reputation: 544

Correct version following your example (not sure if best approach overall):

fun <T: Animal> maker(type: Class<T>): T? {
    return when (type) {
      Cat::class.java -> Cat() as T
      Dog::class.java -> Dog() as T
      else -> null
    }
}

And then to create objects:

val a = maker(Cat::class.java)
val b = maker(Dog::class.java)

Upvotes: 1

Related Questions