2010-05-30 8 views
8

Estoy estableciendo campos públicos del Objectthis a través de la reflexión. Tanto el nombre del campo como el valor se dan como String. Utilizo varios tipos de campos: Boolean, Integer, Float, Double, enum, y String.Establecer campos con reflexión - La cadena no tiene valueOf (String) método

Funciona con todos ellos excepto con String. La excepción que se lanza es que no existe ningún método con la firma String.valueOf(String) ... Ahora uso una solución instanceof sucia para detectar si cada campo es una Cadena y en ese caso simplemente copie el valor en el campo.

private void setField(String field, String value) throws Exception { 
    Field wField = this.getClass().getField(field); 

    if(wField.get(this) instanceof String){ //TODO dirrrrty hack 
    //stupid workaround as java.lang.String.valueOf(java.lang.String) fails... 
    wField.set(this, value); 
    }else{ 
    Method parseMethod = wField.getType().getMethod("valueOf", new Class[]{String.class}); 
    wField.set(this, parseMethod.invoke(wField, value)); 
    } 
} 

¿Alguna idea de cómo evitar esa solución?

¿Cree usted que java.lang.String debería ser compatible con el método valueOf(String)?

Gracias.

+0

Vale la pena mencionar que todos estos Objetos (excepto las enumeraciones) tienen constructores de Cadenas unarios. Así que podrías cambiar a usar esos en todos los casos y solo usar 'valueOf' para tus enums, si eso parece de alguna manera más limpio. – jasonmp85

Respuesta

8

Como habrás notado, no hay String.valueOf(String). Sin embargo, no consideraría su implementación un hack, solo el reconocimiento de la inconsistencia menor en las clases de JDK.

Para una conversión String to Object más robusta, puede considerar usar PropertyEditors, que admite directamente la conversión String to Object: implementación para tipos primitivos y cadenas provistas por defecto. Su método de análisis será consistente y extensible para manejar diferentes tipos. Mejor aún son las clases de conversión en Commons Convert y Spring 3 Type Converters, ya que se centran exclusivamente en la conversión y no en la edición GUI de las propiedades.

+0

PropertyEditors están en uso por Spring, ¿no? Definitivamente son lo que quieres aquí, por cierto. – jasonmp85

+0

Spring usa PropertyEditors, pero con Spring 3.x también las nuevas clases de conversión de tipo que son "más limpias" que PropertyEditors. – mdma

0

¿Alguna idea de cómo evitar esa solución?

Esto depende en gran medida de la implementación de parseMethod.

¿Crees que java.lang.String debería ser compatible con el método valueOf (String)?

¿Para qué? Eso sería un no-op, simplemente devolviendo su parámetro.

+1

parseMethod IS valueOf (String). Entonces no implementé eso solo. sí, sería un no-op, pero haría valueOf más general utilizable en mi humilde opinión. Al menos en este caso. pero tal vez hay otra opción que no conozco. – fabb

+0

@fabb, sería utilizable solo en un caso especial de reflexión, por lo que la mayoría de los desarrolladores de Java nunca lo necesitarían. Y en mi humilde opinión, la solución que muestra es algo con lo que uno puede vivir. –

0

¿Cree java.lang.String debería apoyar el método valueOf(String)?

No. Sería casi no tienen valor fuera de la reflexión y la reflexión no debe ser alentado de todos modos (eficaz de Java 2ª edición, artículo 53: Prefiero interfaces para la reflexión).

+2

Oh, vamos, solo porque Bloch dijo que no es cierto. La reflexión es una herramienta poderosa y maravillosa. Sin embargo, admitiré que esta instancia particular no parece ser su mejor momento. – jasonmp85

0

En caso del de la secuencia:.

Método parseMethod = wField.getType() getMethod ("valueOf", nueva Clase [] {Object.class});

wField.set (this, parseMethod.invoke (wField, valor));

Cuestiones relacionadas