1

Only at run-time am I passed the fully qualified Class name (ie "com.firm.me.MyClass")

I need to instantiate a Generic class defined as, say :

Class A <T>
{
}

Where "T" is the type associated with the passed in fully qualified class name.

I have the following :

Class <?> clazz = Class.forName ("com.firm.me.MyClass");

I want (logically speaking) to have something like ..

A <clazz> myInstance = new A <clazz>;

The use of "clazz" in the positions above gives rise to following errors :

"clazz cannot be resolved to a type".

How can I do what I want (logically) to do.

Many thanks.

user1151685
  • 161
  • 8
  • Due to type erasure `A myInstance` would resolve to `A myInstance` anyways, so even if you got this working, you'd have no benefit from that. What exactly are you trying to do? – Thomas Sep 05 '14 at 09:22
  • I have a serialized persisted data store. There could be several stores and within each store all objects are of the same type.The class example I gave above "class A " instantiates my persister/retriever class. What I want to do is to have the User enter the class name of the type of data persisted in their data store so I can then have a generic command-line based app which can then be used to retrieve their data. I wanted to instantiate the persister/retriever instance based on the fully qualified class name they enter from the command-line – user1151685 Sep 05 '14 at 09:49
  • @user1151685 you should declare a member variable in your class A which is initialized through the constructor.Let me know if the below solution solves your problem – Kumar Abhinav Sep 05 '14 at 10:02

4 Answers4

4

You cannot do such things in Java. Read about type erasure

Besides the issue of type erasure -- which makes this impossible in any event -- you simply can't guarantee that T has an exposed, no-argument constructor!

The traditional workaround is to pass around factory objects that provide methods that can be used to obtain T objects. A simplistic example would be

interface Factory<T> {
  T create();
}

and then your class can get a Factory<T> and call create() on it to get more T's. More sophisticated examples might require additional arguments to a create() method, for example, or overloads.

Ankur Singhal
  • 26,012
  • 16
  • 82
  • 116
0

You should change to Class A to something like this:-

class A<T> {

    Class<T> clazz;

    public A(Class<T> clazz) {
        this.clazz = clazz;
    }

    public static void main(String[] args) throws ClassNotFoundException {
        @SuppressWarnings("unchecked")
        Class<com.firm.me.MyClass> clazz = (Class<MyClass>) Class
                .forName("com.firm.me.MyClass");
        A<MyClass> myInstance = new A<MyClass>(clazz);
    }
}

Just create a constructor which takes a Class object.In this way ,not only are you getting the correct Class Object at runtime,you can use generics to treat your parameterized object the way you want

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
0

In Java, generic types must be resolved on compile time. In fact, they are almost unaccesible at run time due to the famous type-erasure (check this: Get generic type of class at runtime).

Check this question about the same problem: Dynamic Generic Typing in Java

You should stick to the old non-typed A or to A<Object>, where you might include some runtime checks like http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#cast%28java.lang.Object%29 http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isAssignableFrom%28java.lang.Class%29

Community
  • 1
  • 1
jmmurillo
  • 173
  • 6
0

Generics are only used at compile-time for compile-time type checking. Therefore, if a type parameter is not known at compile time, it serves no purpose.

newacct
  • 119,665
  • 29
  • 163
  • 224