Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Create an object whose type is a type parameter

I want to write the equivalent Java code of a C# code.

My C# code is as follows:

public abstract class A<T> where T : A<T>, new()
{
    public static void Process()
    {
        Process(new T());
    }

    public static void Process(T t)
    {
        // Do Something...
    }
}

public class B : A<B>
{
}

public class C : A<C>
{
}

Java equivalent of my code looks like this.

public abstract class A<T extends A<T>>
{
    public static <T extends A<T>> void process()
    {
        process(new T()); // Error: Cannot instantiate the type T 
    }

    public static <T extends A<T>> void process(T t)
    {
        // Do Something...
    }

    public class B extends A<B>
    {
    }

    public class C extends A<C>
    {
    }
}

Here the "new()" syntax in class declaration forces derived classes to write a default constructer which makes possible to call "new T()" from base class. In other words when i am wrting the base class i am sure that the derived class will have a default constructer, so that i can instantiate a derived class object from base class.

My problem in Java is, I cannot instantiate a derived class object from super class. I get "Cannot instantiate the type T" error for "new T()" call. Is there any C# similar way in Java or should I use something like prototype pattern and cloning?

like image 466
Mehmet Ataş Avatar asked Jul 06 '11 13:07

Mehmet Ataş


1 Answers

Java doesn't support reified generics, so there is no equivalent to "new T();". The way I work around this is to use reflection against a type token. The type token indicates what the generic type is.

public abstract class A<T> {
  private Class<T> typeToken;
  // constructor
  public A() {
        typeToken = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
  }
}

Then use reflection to instantiate the class. It's ugly, but it gets the job done.

like image 84
Lawrence McAlpin Avatar answered Oct 04 '22 01:10

Lawrence McAlpin