6

Suppose I have a Java class parameterized on that contains a private T _member. I want to write a default constructor (no arguments), that somehow initializes my T _member to some known, type T specific value (like -1 for Integer, Float.MAX_VALUE for Float...). Is that possible? I tried new T(), but the compiler doesn't like that. Or do I do nothing, and the default constructor is guaranteed to be called for me?

Frank
  • 4,341
  • 8
  • 41
  • 57

4 Answers4

5

Because of type erasure, at runtime "there is no T".

The way around it is to pass an instance of Class<T> into the constructor, like this:

public class MyClass<T> {

    T _member;

    public MyClass(Class<T> clazz) {
        _member = clazz.newInstance(); // catch or throw exceptions etc
    }

}

BTW, this is a very common code pattern to solve the issue of "doing something with T"

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 1
    That clazzy clazz has razz-matazz. :D this is off topic but I couldn't resist. – Wug Aug 03 '12 at 20:32
  • 3
    You mean *type* erasure, I trust? (Would be kinda bad if the *runtime* erased itself ;-) – meriton Aug 03 '12 at 20:36
  • The Class instance passed as an argument is known as a [type token](http://docs.oracle.com/javase/tutorial/extra/generics/literals.html) – hertzsprung Aug 03 '12 at 20:41
3

It's not directly possible, since there's no way to guarantee T even has a default constructor. You could conceivably do it using reflection with newInstance, however. Just be sure to catch any exceptions that may be thrown.

public class MyClass<T> {

    private T _member;

    public MyClass(Class<T> cls) {
        try {
            _member = cls.newInstance();
        } catch (InstantiationException e) {
            // There is no valid no-args constructor.
        }
    }
}
Jon Newmuis
  • 25,722
  • 2
  • 45
  • 57
3

Every field in Java without an initializer expression is automatically initialized to a known default value. And yes, in this case it is a known value of type T -- null.

newacct
  • 119,665
  • 29
  • 163
  • 224
0

In fact there is a way to do this, here's a link to answer on related SO question.

Thus in fact your main question if there's a possibility to get Class of generic member at runtime? Yes, there is - using reflection.

When I came over that answer about a year ago, I tested it and investigated reflection a little bit more. In fact, there were couple of cases when it didn't work as is (be ware of cases with inheritance), but in general it's wrong to claim this is impossible.

However, I strongly do not suggest doing it this way.

EDIT. Surprisingly I found my own comment below that answer :) And in the next comment there's a link by author to the original article on generics' reflection.

Community
  • 1
  • 1
Art Licis
  • 3,619
  • 1
  • 29
  • 49