2012-07-01 25 views
5

Tengo un fragmento de código que se usa para convertir las representaciones de cadena entregadas por Class.getCanonicalName() en sus instancias correspondientes de Class. Esto generalmente se puede hacer usando ClassLoader.loadClass("className"). Sin embargo, falla en tipos primitivos lanzando un ClassNotFoundException. La única solución que encontré fue algo como esto:Uso de tipos primitivos con ClassLoader

private Class<?> stringToClass(String className) throws ClassNotFoundException { 
    if("int".equals(className)) { 
     return int.class; 
    } else if("short".equals(className)) { 
     return short.class; 
    } else if("long".equals(className)) { 
     return long.class; 
    } else if("float".equals(className)) { 
     return float.class; 
    } else if("double".equals(className)) { 
     return double.class; 
    } else if("boolean".equals(className)) { 
     return boolean.class; 
    } 
    return ClassLoader.getSystemClassLoader().loadClass(className); 
} 

Eso parece muy desagradable para mí, por lo que no es cualquier enfoque limpio para esto?

+1

Si estás en Java 7, se podría tratar de un 'switch' en la cadena. –

+0

Ouh, eso es bueno saberlo. Sin embargo, el punto es que no quiero verificar ciertos tipos usando String.equals. Esa es la parte desagradable. – aRestless

Respuesta

3

Dado que tiene una excepción para esto: Class.forName(int.class.getName()), yo diría que este es el camino a seguir.

Comprobando el código de marco de primavera http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/util/ClassUtils.html clase, método resolvePrimitiveClassName, verá que hacen lo mismo, pero con un mapa;). El código fuente: http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.core/3.1.0/org/springframework/util/ClassUtils.java#ClassUtils.resolvePrimitiveClassName%28java.lang.String%29

Algo como esto:

private static final Map primitiveTypeNameMap = new HashMap(16); 
// and populate like this 
primitiveTypeNames.addAll(Arrays.asList(new Class[] { 
     boolean[].class, byte[].class, char[].class, double[].class, 
     float[].class, int[].class, long[].class, short[].class})); 
for (Iterator it = primitiveTypeNames.iterator(); it.hasNext();) { 
    Class primitiveClass = (Class) it.next(); 
    primitiveTypeNameMap.put(primitiveClass.getName(), primitiveClass); 
} 
+0

Sí, 'Class.forName (" int ")' buscaría una clase 'int' en el paquete predeterminado (dice javadoc). Un déficit en el diseño de Java. –

+0

Meh. Las "clases" primitivas inevitablemente serán un sucio truco. –

+0

sí ... desafortunadamente: / –

0

sólo para hacer la vida más divertida, también tendrá problemas con matrices. Esto soluciona el problema del arreglo:

private Pattern arrayPattern = Pattern.compile("([\\w\\.]*)\\[\\]"); 

public Class<?> getClassFor(String className) throws ClassNotFoundException { 
    Matcher m = arrayPattern.matcher(className); 
    if(m.find()) { 
     String elementName = m.group(1); 
     return Class.forName("[L" + elementName + ";"); // see below 
    } 
    return Class.forName(className); 
} 

El ajuste del nombre de clase en [L (nombre de clase); - que obtuve here. No puedo ver una manera más limpia de hacerlo, pero estoy seguro de que debe haber uno.

Por supuesto, necesitará una gran variedad de tipos primitivos un conjunto adicional de la lógica del caso especial ...

Cuestiones relacionadas