2017-03-05 2 views
1

Bei Verwendung von Java Reflection können wir ein privates Feld festlegen, ohne den Parametertyp angeben zu müssen.Festlegen privater Felder mit Java Reflection

Zum Beispiel, wenn dies meine Child Klasse,

package reflection; 

public class Child { 

    private String name; 
    private Integer value; 
    private boolean flag; 


    public String getLName() 
    { 
     return this.name; 
    } 

    public void setName(String name) 
    { 
     this.name = name; 
    } 

    public Integer getValue() 
    { 
     return this.value; 
    } 

    public void setValue(Integer value) 
    { 
     this.value = value; 
    } 

    public boolean getFlag() 
    { 
     return this.flag; 
    } 

    public void setFlag(boolean flag) 
    { 
     this.flag = flag; 
    } 

    public String toString() 
    { 
     return "Name" + this.name; 
    } 
} 

I Felder dieser Child Klasse in meiner Tester Klasse festlegen möchten.

package reflection; 

public class Tester { 

    public static void main(String args[]) throws Exception 
    { 



     Class<?> clazz = Class.forName("reflection.Child"); 
     Object cc = clazz.newInstance(); 
     cc.getClass().getMethod("setName", String.class).invoke(cc,"AAA"); 
    } 
} 

Hier setze ich den Wert von Name Feld. In der Zeile,

cc.getClass().getMethod("setName", String.class).invoke(cc,"AAA"); 

Ich habe String.class verwendet. Gibt es eine Möglichkeit, dies zu tun, ohne den Feldtyp angeben zu müssen. Kann Java den Typ irgendwie automatisch identifizieren? Dies liegt daran, dass ich den Namen, Wert und Flag-Daten aus einer csv-Datei erhalten werde, und ich möchte alle drei Felder in einer einzelnen Zeile mit einer Schleife festlegen. „SetName“, „setValue“ und „SetFlag“ und dann möchte ich etwas von der folgenden

cc.getClass().getMethod(array[index]).invoke(cc,data); 

Ich weiß, dass die obige Aussage ist falsch verwenden, aber gibt es - ich ein Array von String mit Werten erklären eine Alternative dazu?

+1

Schleife durch die Methoden der Klasse verwenden könnte und finde den Namen setName. Bete, dass es nicht überladen ist. Beachten Sie, dass dies nichts mit privaten Feldern zu tun hat. Sie rufen hier öffentliche Methoden auf und legen keine privaten Felder fest. Wie gesagt, ist Reflektion, wie fast alle Fragen im Zusammenhang mit Reflektion, wahrscheinlich nicht der beste Weg, um Ihr Problem zu lösen. Warum nicht ein Array von Consumer verwenden, das zum Beispiel 'n -> c.setName (n)' anstelle eines Arrays von Strings enthält? –

Antwort

2

Holen Sie sich alle Methoden und finden Sie die passende ein, die Informationen geben über die Parameter:

String name; 
String value; 
Method[] methods = Child.class.getMethods(); 
for (Method method : methods) { 
    if (!method.getName().equals(name)) 
     continue; 
    Class<?> paramType = method.getParameterTypes()[0]; 
    //You will have to figure how to convert the String value to the parameter. 
    method.invoke(child, paramType.cast(value)); // for example 
} 
+0

Gibt es eine Möglichkeit, nicht alle Methoden zu durchlaufen? –

+0

@ GrzegorzGórkiewicz nicht, es sei denn, Sie kennen den Parametertyp, den Sie sagten, dass Sie nicht wissen. Wenn Sie den Parametertyp kennen, können Sie 'Child.class.getMethod (name, parameterClass)' aufrufen, um die genaue Methode zu erhalten. – Bohemian

+0

Aber der Parametertyp ist immer ... 'value.getClass()' ... d. H. 'Data.getClass()' wie in meiner Antwort oder? –

0

Sie Apache Commons FieldUtils.writeDeclaredField

Child childObject = new Child(); 
FieldUtils.writeDeclaredField(childObject, "name", "John", true);