Pregunta

Estoy buscando implementar algo en Java en la línea de:

class Foo{
 private int lorem; //
 private int ipsum;      

 public setAttribute(String attr, int val){
  //sets attribute based on name
 }

 public static void main(String [] args){
  Foo f = new Foo();
  f.setAttribute("lorem",1);
  f.setAttribute("ipsum",2);
 }

 public Foo(){}
}

... donde una variable se establece en función del nombre de la variable sin los nombres de las variables codificados y sin utilizar ninguna otra estructura de datos. ¿Es esto posible?

¿Fue útil?

Solución

Así es como puede implementar setAttribute usando la reflexión (he cambiado el nombre de la función; hay diferentes funciones de reflexión para diferentes tipos de campo):

public void setIntField(String fieldName, int value)
        throws NoSuchFieldException, IllegalAccessException {
    Field field = getClass().getDeclaredField(fieldName);
    field.setInt(this, value);
}

Otros consejos

En general, desea usar Reflection. Aquí hay una buena introducción a tema con ejemplos

En particular, el " Cambio de valores de los campos " sección describe cómo hacer lo que le gustaría hacer.

Observo que el autor dice: "Esta característica es extremadamente poderosa y no tiene equivalente en otros lenguajes convencionales". Por supuesto, en los últimos diez años (el artículo fue escrito en 1998) hemos visto grandes avances en lenguajes dinámicos. Lo anterior se hace con bastante facilidad en Perl, Python, PHP, Ruby, etc. Sospecho que esta es la dirección de la que podría haber venido en función de la "evaluación" etiqueta.

Además, eche un vistazo a BeanUtils , que puede ocultar parte de la complejidad de utilizar la reflexión de usted.

La pregunta es específica para ints, lo cual es útil, sin embargo, aquí hay algo un poco más general. Este tipo de método es útil si está cargando representaciones de String de pares de nombre de campo / valor de campo.

import java.lang.reflect.Field;

public class FieldTest {

    static boolean isValid = false;
    static int count = 5;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        FieldTest test = new FieldTest();
        test.setProperty("count", "24");
        System.out.println(count);
        test.setProperty("isValid", "true");
        System.out.println(isValid);
    }

    public void setProperty(String fieldName, String value) throws NoSuchFieldException, IllegalAccessException {
        Field field = this.getClass().getDeclaredField(fieldName);
        if (field.getType() == Character.TYPE) {field.set(getClass(), value.charAt(0)); return;}
        if (field.getType() == Short.TYPE) {field.set(getClass(), Short.parseShort(value)); return;}
        if (field.getType() == Integer.TYPE) {field.set(getClass(), Integer.parseInt(value)); return;}
        if (field.getType() == Long.TYPE) {field.set(getClass(), Long.parseLong(value)); return;}
        if (field.getType() == Float.TYPE) {field.set(getClass(), Float.parseFloat(value)); return;}
        if (field.getType() == Double.TYPE) {field.set(getClass(), Double.parseDouble(value)); return;}
        if (field.getType() == Byte.TYPE) {field.set(getClass(), Byte.parseByte(value)); return;}
        if (field.getType() == Boolean.TYPE) {field.set(getClass(), Boolean.parseBoolean(value)); return;}
        field.set(getClass(), value);
    }

}

Dependiendo del uso, puede usar la reflexión como se indicó anteriormente, o tal vez un HashMap sería más adecuado ...

Es posible que desee almacenar en caché algunos de los datos de reflexión mientras lo hace:

import java.lang.reflect.Field;
import java.util.HashMap;

class Foo {
    private HashMap<String, Field> fields = new HashMap<String, Field>();

    private void setAttribute(Field field, Object value) {
        field.set(this, value);
    }

    public void setAttribute(String fieldName, Object value) {
        if (!fields.containsKey(fieldName)) {
            fields.put(fieldName, value);
        }
        setAttribute(fields.get(fieldName), value);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top