Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to create new instance of generic class in kotlin?

I use following initialization:

val entityClass = javaClass<Class<T>>() var entity = entityClass.newInstance().newInstance() 

but it's wrong and causes IllegalAccessException on java.lang.Class.newInstance(Class.java:1208)

like image 787
pawegio Avatar asked Nov 18 '14 10:11

pawegio


People also ask

How do I create an instance of a class in Kotlin?

In Kotlin, we cannot create an instance of an abstract class. Abstract classes can only be implemented by another class which should be abstract in nature. In order to use an abstract class, we need to create another class and inherit the abstract class.

How will you create generic instance class?

To construct an instance of a generic type GetType(String) method overload with a string describing the type, and by calling the GetGenericTypeDefinition method on the constructed type Dictionary\<String, Example> ( Dictionary(Of String, Example) in Visual Basic).

How do I create a generic class in Kotlin?

When we want to assign the generic type to any of its super type, then we need to use “out” keyword, and when we want to assign the generic type to any of its sub-type, then we need to use “in” keyword. In the following example, we will use “out” keyword. Similarly, you can try using “in” keyword.

How do I create a generic function Kotlin?

Kotlin generic extension function example As extension function allows to add methods to class without inherit a class or any design pattern. In this example, we add a method printValue()to ArrayList class of generic type. This method is called form stringList. printValue() and floatList.


1 Answers

If you let IntelliJ add explicit type information, you see that entityClass is actually of type Class<Class<String>>. I'm not sure if that's what you want. In line 2 you are first creating an instance of Class<T> and then one of T but that's not possible anyway, because the generic information about T is lost at runtime. Apart from that you can't instantiate class objects directly.

Solution

One possible solution would be to add a parameter of type Class<T> to your function or class and use it to instantiate objects like this.

fun <T> foo(entityClass: Class<T>) {     var entity: T = entityClass.newInstance() }  fun test() {     foo(Object::class.java) } 

But there's actually a more elegant solution without the use of reflection. Define a parameter of method type () -> T and use constructor references. Here's my related question about constructor references and here's the code:

fun <T> foo2(factory: () -> T) {     var entity: T = factory() }  fun test() {     foo2(::Object) } 
like image 96
Kirill Rakhman Avatar answered Sep 19 '22 06:09

Kirill Rakhman