Creating an object of the same class as the parameterized type

222 Views Asked by At

Here's the code:

package Fabrika.Trake;
import Vozila.*;

public class Traka<T extends Vozilo> extends Thread
{
    protected int vrijemeRada;
    ...

    @Override
    public void run()
    {
        while(true)
        {
            //I want to create the object here
        }
    }
}

Now, let's say I have a class called Auto which extends Vozilo.

I'd like to know if there is a way of constructing an object of type T without using reflection. Something like:

T object = new T(); 

This, of course, is completely incorrect, but it just serves as an illustration of what I'd like to do. :)

3

There are 3 best solutions below

0
On BEST ANSWER

You can't do this with just the generic type T.

To create an instance you need a Class instance.

E.g.:

public class Traka<T extends Vozilo> extends Thread
{
    protected int vrijemeRada;
    ...

    private Class<T> type;

    public Traka(Class<T> type) {
        this.type = type;
    }

    @Override
    public void run()
    {
        while(true)
        {
            T newInstance = type.newInstace(); // this uses the default constructor
        }
    }
}

Usage:

Traka<Auto> autoTraka = new Traka(Auto.class);

The problem is that the generic type information T is erased at runtime. Therefore you need a Class instance to represent the type at runtime.

0
On

There is a special pattern for this: pass Class instance to the constructor of Traka, store it in a private variable, and the use that class to instantiate new objects, like this:

public class Traka<T extends Vozilo> extends Thread {
    private Class<T> theClass;
    public Traka(Class<T> theClass) {
        this.theClass = theClass;
    }
    ...
    @Override
    public void run() {
        while(true) {
            T inst = theClass.newInstance();
        }
    }
}

Note: In case you were wondering why Class became parameterized in Java 5, the pattern above is the answer.

0
On

Use a type token.

public class Traka<T extends Vozilo> extends Thread
{
    private Class<T> type;
    protected int vrijemeRada;
    ...

    public Traka(Class<T> type) {
        this.type = type;
   }

    @Override
    public void run()
    {
        while(true)
        {
            //I want to create the object here
            T object = type.newInstance();
        }
    }
}

This works - of course - only with constructors that have a known number of arguments. My example uses a no-arg constructor.

And: Do not extend Thread! Implement Runnable instead. And then uses those runnables, wherever you need them.