9

How can I use reflection to create a generic parameterized class in Java?

I have

public class SomeClass<T> {
   public SomeClass<T>() {
   }
}

and I need an instance of it.

I've tried variations of

Class c = Class.forName("SomeClass");

but could not find a syntax that would allow me to get an appropriately typed instance, like, say

SomeType instance = (SomeType)Class.forName("SomeClass<SomeType>").createInstance();

So, how could I go about doing this?

3 Answers 3

9

Java uses erasure-based generics (i.e., the type parameters are erased at runtime—for example, List<Integer> and List<String> are treated as the same type at runtime). Since reflection is inherently a runtime feature, the type parameters are not used or involved at all.

In other words, you can only instantiate the raw type (SomeClass, not SomeClass<T>) when you're using reflection. You will then have to manually cast the type to the generic version (and generate an unchecked warning).

Sign up to request clarification or add additional context in comments.

11 Comments

I can't manually cast the type to the generic version, as I know the type only by its string name. This is why I need a means of obtaining a correctly-typed instance without knowing more than the types' names as Strings.
@luvieere: Then just use SomeClass<?> in your source code. The type parameter is ever only useful at compile-time, and since you don't have that info at compile-time, ? is the way to express that.
SomeClass<Type1> has a radically different behavior than SomeClass<Type2>. How would this be addressed by using SomeClass<?>?
@luvieere: In Java, at runtime SomeClass<Type1> is the same type as SomeClass<Type2>: both are of type SomeClass. That is why the kinds of things you can do with type parameters in Java is very restricted compared to what you can do in, say, C#. (Java == erasure generics, i.e., type parameters lost at runtime. C# == reified generics, i.e., type parameters preserved at runtime.)
I managed to rewrite my code not to rely on the type's names anymore and now, indeed, the instantiation works without hassle.
|
2

See/search for "Type erasure". Generics are for compile time and they are not availble at runtime so what you are trying is not possible. You need to use the raw type for reflection

Comments

1

Because of type erasure, at runtime SomeClass is all there is left of SomeClass<SomeType>.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.