2012-07-01 20 views
5

Ho una parte di codice utilizzata per trasformare le rappresentazioni di stringa fornite da Class.getCanonicalName() nelle corrispondenti istanze di Class. Questo di solito può essere fatto usando ClassLoader.loadClass("className"). Tuttavia, non riesce su tipi primitivi lanciando uno ClassNotFoundException. L'unica soluzione mi sono imbattuto è stato qualcosa di simile:Utilizzo di tipi primitivi 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); 
} 

Che sembra molto brutto per me, quindi non v'è alcun metodo pulito per questo?

+1

Se siete in Java 7, si potrebbe provare un 'switch' sulla corda. –

+0

Ouh, è bello saperlo. Tuttavia, il punto è che non voglio controllare determinati tipi usando String.equals. Questa è la parte cattiva. – aRestless

risposta

3

Poiché si dispone di un'eccezione per questo: Class.forName(int.class.getName()), direi che questa è la strada da percorrere.

Controllare il codice di struttura Spring codice , metodo resolvePrimitiveClassName, vedrete che fanno la stessa cosa, ma con una mappa;). Codice sorgente: 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

Qualcosa di simile a questo:

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 ")' cercherebbe una classe 'int' nel pacchetto predefinito (dice javadoc). Un deficit nel design java. –

+0

Meh. Le "classi" primitive saranno inevitabilmente un vero e proprio hack. –

+0

sì ... purtroppo: / –

0

solo per rendere la vita più divertente, si avrà anche problemi con gli array. Questo risolve il problema dell'array:

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); 
} 

Il wrapping del nome classe in [L (nome classe); - che ho acquistato here. Non riesco a vedere un modo più pulito di farlo, ma sono sicuro che ce ne deve essere uno.

Naturalmente un array di tipi primitivi avrà bisogno di un ulteriore insieme di logica special-case ...

Problemi correlati