2008-11-09 9 views
11

Ich bin auf der Suche nach dem Vorbild des etwas in Java zu implementieren:Variablen mit Namen Einstellung in Java

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(){} 
} 

... wo eine Variable basierte, ohne dass die Variablennamen auf dem Variablennamen hartcodiert und ohne irgendwelche anderen Datenstrukturen zu verwenden. Ist das möglich?

Antwort

24

Hier ist, wie Sie setAttribute mit Reflexion implementieren könnte (ich habe die Funktion umbenannt, es gibt unterschiedliche Reflexionsfunktionen für verschiedene Feldtypen):

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

Im Allgemeinen möchten Sie Reflection verwenden. Hier ist eine gute Einführung in die topic with examples

Insbesondere der Abschnitt "Ändern der Werte von Feldern" beschreibt, wie Sie tun, was Sie tun möchten.

Ich bemerke, dass der Autor sagt: "Diese Funktion ist extrem leistungsfähig und hat keine Entsprechung in anderen konventionellen Sprachen." Natürlich haben wir in den letzten zehn Jahren (der Artikel wurde 1998 geschrieben) große Fortschritte in dynamischen Sprachen gemacht. Das oben genannte ist ziemlich einfach in Perl, Python, PHP, Ruby und so weiter. Ich vermute, das ist die Richtung, aus der Sie vielleicht aufgrund des "eval" -Tags gekommen sind.

+0

Verbindung scheint gebrochen zu werden, ( – Vlad

+0

ich den Link behoben haben –

+0

Verbindung wieder gebrochen – SimonPip

3

Werfen Sie auch einen Blick auf BeanUtils, die einige der Komplexität der Verwendung von Reflexion von Ihnen verbergen können.

0

Vielleicht möchten einige der Reflexionsdaten zwischenzuspeichern, während Sie ist es:

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

Warum sich die Mühe, wenn die Reflexionsschicht schon.. macht dieses Caching? Lesen Sie den Quellcode für java.lang.Class und sehen Sie selbst; es behandelt sogar den Cache, wenn eine Klasse neu geladen wird. –

1

Je nach Verwendungszweck können Sie Reflektion verwenden, wie oben empfohlen, oder vielleicht wäre ein HashMap besser geeignet ...

1

Die Frage ist spezifisch für Ints, was hilfreich ist, aber hier ist etwas etwas allgemeiner. Dieser Methodentyp ist nützlich, wenn Sie in String Darstellungen von Feldnamen/Feldwertpaaren laden.

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

} 
Verwandte Themen