I'm guessing there is absolutely no way I can do something like:
Class c = Class.forName("Processor<Integer, String>");
in Java? (where I defined Processor previously, of course).
I'm guessing there is absolutely no way I can do something like:
Class c = Class.forName("Processor<Integer, String>");
in Java? (where I defined Processor previously, of course).
Absolutely no way as generic arguments can exist only at compile time. Class
object is the same on runtime. It is not class template as in C++. Type parameters are just information for java compiler.
You can try to accomplish something similar by creating a class :
class IntStringProcessor extends Processor<Integer, String> {}
and Class c = Class.forName("IntStringProcessor");
On runtime you can get actual Processor
type parameters via c.getGenericSuperclass()
but this extends the question I guess.
EDIT: Another idea
Your Processor
may keep classess as parameters and then:
Class c1 = Class.forName("java.lang.Integer");
Class c2 = Class.forName("java.lang.String");
Processor = new Processor(c1,c2);
Your processor is now not generic but uses Class instances inside. As I said, there is no way to create generic instance on runtime because generics exist only at compile time.
First let me straighten something. There is no Class
object in Java for Processor<Integer, String>
. There is only one Class
object for Processor
, namely Processor.class
and all generic instantiations share the same Class
object:
Processor<Integer, String> x = new Processor<Integer, String>();
Processor<Character, Byte> y = new Processor<Character, Byte>();
System.out.println(x.getClass() == y.getClass()); // prints true
Having said that, if all you need is to have tokens for generic types to pass around, you can use a third party implementation. Here I use Java ClassMate:
TypeResolver typeResolver = new TypeResolver();
// type token for Processor<Integer, String>
ResolvedType type = typeResolver.resolve(Processor.class, Integer.class, String.class);
System.out.println("type = " + type);
If you read names of Java types as String
's from a file, you probably want to use Class.forName()
instead of my .class
literals.
You'll have to parse <
, >
brackets yourself, but that should be easy, as those single characters always mean the same thing in Java type names...
You can form nested parameters like this:
// type token for Processor<Processor<Integer, String>, Character>
ResolvedType type = typeResolver.resolve(Processor.class,
typeResolver.resolve(Processor.class, Integer.class, String.class),
typeResolver.resolve(Character.class)
);
System.out.println("type = " + type);
If you want to create type tokens for types you know at compilation time, you can use the so-called super-type-token pattern. Just put any type name you need inside new GenericType<...>() {}
:
type = typeResolver.resolve(new GenericType<Processor<Processor<Integer, String>, Character>>() {});
System.out.println("type = " + type);