We can make class Foo <T>
, why can't I call new T()
?
I tried to understand, I know that T
is a type variable, but didn't get that answer... which is asked by friend, am also eager to know the answer... please, thanks in advance.

- 195,646
- 29
- 319
- 436

- 2,290
- 1
- 18
- 29
-
2See [What are Reified Generics, how do they solve the Type Erasure problem and why can't they be added without major changes?](http://stackoverflow.com/questions/879855) – McDowell Aug 01 '12 at 12:37
3 Answers
It's because of type erasure. The class of T is known only at compile time, not at runtime.
There is a workaround. You can add an additional method parameter of type Class<T>
and then call newInstance
on that parameter. Make sure you read the docs for reflection and otherwise know what you're getting into before you try this.

- 24,950
- 9
- 62
- 84
-
There is a special case `class Bar extends Foo
` where the generics info remains at runtime. Bar will know it's type parameter is Baz. Via reflection you can then instantiate that Baz. You will probably need Baz to have a zero argument constructor. It doesn't matter if it's private, reflection can work around that. The thing is you can write the code that uses reflection on the parent class Foo. – Tomas Lazaro Aug 01 '12 at 12:45
Because you cannot know if T is even instantiable, it could have a private constructor.
Imagine:
class Foo<T> {
public Foo() {
new T();
}
}
class Bar {
private Bar() {}
}
class FooBar {
public FooBar() {
Foo<Bar> foo = new Foo<>();
}
}

- 7,865
- 5
- 30
- 55

- 9,825
- 1
- 35
- 72
The problem is Type Erasure as noted but Taymon. You can work around it using some reflection and sub classing so type information remains at runtime.
Notice that it does work for Bar but doesn't for Qux. Notice that Bar specifies at compile it's type parameter by extending Foo with a fixed type argument Baz. The instantiation also relies on an accessible zero argument constructor.
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import sun.reflect.generics.reflectiveObjects.TypeVariableImpl;
// Made abstract so we can use getClass().getGenericSuperclass() and rely on subclasses
// specifying it's type parameter.
public abstract class Foo<T> {
public T instantiateTypeParameter() throws Exception {
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) type;
Type typeArg = paramType.getActualTypeArguments()[0]; // We know it's only one, T
if (typeArg instanceof TypeVariableImpl) {
// Type is not specified. Can't do anything to retrieve it at runtime
TypeVariableImpl typeVar = (TypeVariableImpl) typeArg;
for (TypeVariable var : typeVar.getGenericDeclaration().getTypeParameters()) {
System.out.println("Type: " + var);
}
return null;
} else {
Class<?> clazz = (Class<?>) typeArg;
return (T) clazz.getConstructor().newInstance();
}
} else {
System.out.println("IMPOSSIBRUUU");
return null;
}
}
}
public class Bar extends Foo<Baz> {
}
public class Qux<T> extends Foo<T> {
}
public static void main(String[] args) throws Exception {
Bar bar = new Bar();
Baz baz = bar.instantiateTypeParameter(); // Note that you know that it returns Baz
System.out.println("Baz: " + baz); // It works!
Qux<Baz> qux = new Qux<Baz>();
Baz baz2 = qux.instantiateTypeParameter(); // Will be null
System.out.println("Baz2: " + baz2);
}

- 315
- 1
- 8