0

I've read a lot of other questions out there, but I cannot find one with similar case as mine. Assume I have the following code:

public class TestClass
{
    public Class clazz;

    public TestClass(Object input)
    {
        this.clazz = ........ ?? // how to get String.class from "input" parameter?
    }

    public static void main(String[] args)
    {
        List<String> all = new ArrayList<>();
        new TestClass(all);
    }
}

The constructor of TestClass has 1 parameter which is an Object type. At runtime, it receives a variable of type List, but the actual instance is an ArrayList. Inside the TestClass constructor, I want to extract the generic type of that ArrayList from input parameter. The expected result should be String.class object, which can be stored in clazz variable.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
user3009097
  • 185
  • 1
  • 1
  • 8
  • "*Inside the TestClass constructor, I want to extract the generic type of that ArrayList from input parameter.*" - Due to [type erasure](https://docs.oracle.com/javase/tutorial/java/generics/erasure.html), this is not possible. – Turing85 Sep 11 '22 at 06:18
  • That's a different case @samabcde. His parameter type is equal to variable type which was passed on to it. In my case, the parameter type is *Object* and not the same as the variable type which was passed on to it. – user3009097 Sep 12 '22 at 09:05

1 Answers1

0

This is not possible in Java because the generic type is only saved during compile type. You cannot get type runtime as you are expecting. Internally it will create every type as Object only which is base class for all java class. This concept is called as type erasure. You can read about it more here.

One way you can do is something like this. It will work only if List is not empty.

public class TestClass{
    public Class clazz;

    public TestClass(List<String> input) {
        if (input instanceof ArrayList) {
            if(!input.isEmpty()){
                this.clazz = input.get(0).getClass();
                System.out.println(clazz);
            }
        }
    }

    public static void main(String[] args) {
        List<String> all = new ArrayList<>();
        all.add("21");
        new TestClass(all);
    }
}
Gowtham K K
  • 3,123
  • 1
  • 11
  • 29
  • I think this is the closest workaround, but not the best one. Because the generic type is known at compile time. And like you said, it's due to erasure concept. – user3009097 Sep 12 '22 at 09:07
  • 1
    Now change the line `List all = new ArrayList<>();` to `List all = new ArrayList<>();` and you’ll see that the type printed, is not related to the generic type of `all`. – Holger Sep 14 '22 at 07:34