tipos - Establecer variables por nombre en Java
variables de referencia en java (6)
Además, eche un vistazo a BeanUtils que puede ocultar parte de la complejidad de usar su reflejo.
Estoy buscando implementar algo en Java a lo largo de las líneas 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 que los nombres de las variables estén codificados y sin utilizar ninguna otra estructura de datos. es posible?
Así es cómo podría implementar setAttribute
utilizando la reflexión (he cambiado el nombre de la función, hay diferentes funciones de reflexión para diferentes tipos de campos):
public void setIntField(String fieldName, int value)
throws NoSuchFieldException, IllegalAccessException {
Field field = getClass().getDeclaredField(fieldName);
field.setInt(this, value);
}
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);
}
}
Dependiendo del uso, puede usar la reflexión como se indicó anteriormente, o tal vez un HashMap sería más adecuado ...
En general, quiere usar Reflection. Aquí hay una buena introducción al tema con ejemplos
En particular, la sección "Cambio de valores de los campos" 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 los lenguajes dinámicos. Lo anterior se realiza con bastante facilidad en Perl, Python, PHP, Ruby, etc. Sospecho que esta es la dirección de la que podría haber venido basado en la etiqueta "eval".
La pregunta es específica de Ints, lo que es útil, sin embargo, aquí hay algo un poco más general. Este tipo de método es útil si está cargando en 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);
}
}