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?

4 Answers 4

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"

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

3 Comments

That clazzy clazz has razz-matazz. :D this is off topic but I couldn't resist.
You mean type erasure, I trust? (Would be kinda bad if the runtime erased itself ;-)
The Class instance passed as an argument is known as a type token
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.

Comments

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.
        }
    }
}

4 Comments

-1 You can't do anything with T. This answer completely won't work. See my answer for why
OMG! You totally changed your answer and copy-pasted mine over the top of it. Have you no honour?
I did not copy and paste your answer. I added an example of my second and third sentences. I've upvoted your answer; no harm intended here, my friend.
+1 for pointing out that T may not have a default constructor.
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.

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.