Frage

Ich bin auf der Suche nach dem Vorbild des etwas in Java zu implementieren:

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 wird basierend auf den Variablennamen ohne die Variablennamen hartcodiert und ohne irgendwelche andere Datenstrukturen zu verwenden. Ist das möglich?

War es hilfreich?

Lösung

Hier ist, wie Sie setAttribute implementieren könnte mithilfe von Reflektion (ich die Funktion umbenannt haben, 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);
}

Andere Tipps

In der Regel wollen Sie Reflexion verwenden. Hier ist eine gute Einführung in die Thema mit Beispielen

Insbesondere die „Werte im Wandel von Fields“ wird beschrieben, wie zu tun, was Sie tun möchten.

Ich nehme zur Kenntnis, dass der Autor sagt: „Diese Funktion ist extrem leistungsfähig und hat keine Entsprechung in anderen herkömmlichen Sprachen.“ Natürlich haben wir große Fortschritte in den letzten zehn Jahren (1998 wurde der Artikel geschrieben) in dynamischen Sprachen gemacht gesehen. Die oben ist ziemlich leicht gemacht in Perl, Python, PHP, Ruby, und so weiter. Ich vermute, dies ist die Richtung Sie basiert auf dem „eval“ Tag haben könnten.

Werfen Sie auch einen Blick auf BeanUtils , die von einigen der Komplexität der Verwendung von Reflexion verstecken Sie.

Die Frage ist spezifisch für ints, was hilfreich ist, aber hier ist etwas, etwas allgemeiner. Diese Art von Verfahren ist nützlich, wenn Sie in String Darstellungen von Feldnamen / Feldwertepaaren geladen werden.

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

}

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

Sie möchten vielleicht einige der Reflexionsdaten zwischenzuspeichern, während Sie gerade dabei sind:

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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top