2

I have the same logic in classes creation, but actual classes are different. Is it possible somehow to create an instance of a parameterized class?

Here is an example:

public class MyClass <E extends MyEntityClass> {
    public List<E> myList = new LinkedList<>();

    public MyClass(JsonArray params) {
        for(JsonElement param : params){
            myList.add(new E(param));
        }
    }
}

MyEntityClass - is the super class which has the constructor which accepts JsonElement.

I know that Java doesn't allow to create the parameterized class, but is it possible to solve somehow this problem?

Oleksandr
  • 3,574
  • 8
  • 41
  • 78
  • You could try to combine [Get generic type of class at runtime ](https://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime) wuth [Can I use Class.newInstance() with constructor arguments? ](http://https://stackoverflow.com/questions/234600/can-i-use-class-newinstance-with-constructor-arguments) – Turo Jul 30 '17 at 19:20
  • Possible duplicate of [Create instance of generic type in Java?](https://stackoverflow.com/questions/75175/create-instance-of-generic-type-in-java) – Stijn Haezebrouck Jul 30 '17 at 19:20

1 Answers1

3

Generics are erased after compilation.
So of course, instantiating directly a parameterized type as you try to do is not possible.

As workaround, you could pass a factory method to your constructor.

With functional interface, you could add a parameter Function<JsonElement,E> in your constructor and use it to create instances of the generic element :

public class MyClass<E extends MyEntityClass> {
    public List<E> myList = new LinkedList<>();

    public MyClass(JsonArray params, Function<JsonElement, E> factoryE) {
        for(JsonElement param : params){
            myList.add(factoryE.apply(param));
        }
    }
}

And you could instantiate your class in this way :

MyClass<MyEntityClass> myClass = new MyClass<MyEntityClass>(MyEntityClass::new);

With a MyEntityClass defined with a constructor that accepts a JsonElement parameter :

public class MyEntityClass {
    ...
    public MyEntityClass(JsonElement jsonElement){
      ...
    }
   ...
}

Of course, you can achieve the same thing without functional interface but it would be more verbose.

davidxxx
  • 125,838
  • 23
  • 214
  • 215