Dynamically find the class that represents a primitive Java type
The Class
instances for the primitive types are obtainable as you said using e.g. int.class
, but it is also possible to get the same values using something like Integer.TYPE
. Each primitive wrapper class contains a static field, TYPE
, which has the corresponding primitive class instance.
You cannot obtain the primitive class via forName
, but you can get it from a class which is readily available. If you absolutely must use reflection, you can try something like this:
Class clazz = Class.forName("java.lang.Integer");
Class intClass = clazz.getField("TYPE").get(null);
intClass.equals(int.class); // => true
The Spring framework contains a utility class ClassUtils which contains the static method forName. This method can be used for the exact purpose you described.
In case you don’t like to have a dependency on Spring: the source code of the method can be found e. g. here on their public repository. The class source code is licensed under the Apache 2.0 model.
Note however that the algorithm uses a hard-coded map of primitive types.
Edit: Thanks to commenters Dávid Horváth and Patrick for pointing out the broken link.
Probably you just need to map the primitives and for the rest of the classes perform the "forName" method:
I would do something like:
void someWhere(){
String methodDescription = "doSomething int double java.lang.Integer java.lang.String"
String [] parts = methodDescription.split();
String methodName= parts[0]
Class [] paramsTypes = getParamTypes( parts ); // Well, not all the array, but a, sub array from 1 to arr.length..
Method m = someObject.class.getMethod( methodName, paramTypes );
etc. etc etc.
}
public Class[] paramTypes( String [] array ){
List<Class> list = new ArrayList<Class>();
for( String type : array ) {
if( builtInMap.contains( type )) {
list.add( builtInMap.get( type ) );
}else{
list.add( Class.forName( type ) );
}
}
return list.toArray();
}
// That's right.
Map<String,Class> builtInMap = new HashMap<String,Class>();{
builtInMap.put("int", Integer.TYPE );
builtInMap.put("long", Long.TYPE );
builtInMap.put("double", Double.TYPE );
builtInMap.put("float", Float.TYPE );
builtInMap.put("bool", Boolean.TYPE );
builtInMap.put("char", Character.TYPE );
builtInMap.put("byte", Byte.TYPE );
builtInMap.put("void", Void.TYPE );
builtInMap.put("short", Short.TYPE );
}
That is, create a map where the primitives types are stored and if the description belong to a primitive then use the mapped class. This map may also be loaded from an external configuration file, to add flexibility so you add String as a built in instead of java.lang.String or potentially have method like this.
"doSomething string yes|no "
There are lots of this kind of code in OS projects like Struts, Hibernate, Spring and Apache libs ( just to mention a few ) , so you don't need to start from zero.
BTW. I did not compile the above code, but I'm pretty sure it works with little modifications don't down vote me for that.