因此,我希望通过反射从另一个类访问一个类的数据成员字段。我一直无法弄清楚,在通过反射获得数据成员之后,如何更改字段的值。我真的不知道如何更好地表达它,所以我会让代码为我说话。
下面是调用按钮的处理程序类。下面是其余的类,我将对其功能进行解释。
import java.awt.*;
import java.awt.event.*;
public class SimHandler extends Frame{
public myValveButton but0,but1,but2,but3,but4,but5,but6,but7;
public SimHandler(){
super("Liquer Plant Control Panel");
this.setLayout(null);
this.setFont(new Font("Helvetica", Font.PLAIN, 14));
this.setBackground(Color.black);
but0 = new myValveButton("S1a",100,40,this);
but1 = new myValveButton("S1b",100,140,this);
but2 = new myValveButton("S2a",200,40,this);
but3 = new myValveButton("S2b",200,140,this);
but4 = new myValveButton("S3a",100,240,this);
but5 = new myValveButton("S3b",100,340,this);
but6 = new myValveButton("S4a",200,240,this);
but7 = new myValveButton("S4b",200,340,this);
this.setSize(335,410);
this.setLocation(100,100);
this.setVisible(true);
this.toFront();
this.setResizable(false);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}实际上,这就是我试图使用反射来更改Silo实例状态值的地方。下面是LiqPlantSim和Silo类。正如您所看到的,状态变量不能以这种方式解析,在进行了相当多的googling搜索之后,我不知道如何使它工作。
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.*;
import java.lang.reflect.Field;
public class myValveButton extends Button{
String label;
public myValveButton(String label,int x,int y,Frame f){
super(label);
this.label = label;
this.addActionListener(new myValveButtonHandler(label));
f.add(this);
this.setBounds(x, y, 35, 30);
}
}
class myValveButtonHandler implements ActionListener{
Field f;
String label;
public myValveButtonHandler(String label){
this.label = label;
}
public void actionPerformed(ActionEvent pushButton){
try {
f = LiqPlantSim.class.getDeclaredField("silo"+label.split("")[1]);
System.out.println(f);
//f.state = "full" //Eclipse says 'state cannot be resolved to a type or is not a field'
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
System.out.println(label.split("")[2]);
}
}这是LiqPlantSim类。
import java.util.HashMap;
import java.util.Map;
public class LiqPlantSim{
public Silo silo1,silo2,silo3,silo4;
public Pipe pipe;
public LiqPlantSim(){
silo1 = new Silo(false,false);
silo2 = new Silo(false,true);
silo3 = new Silo(true,false);
silo4 = new Silo(true,true);
pipe = new Pipe();
}
}这是筒仓班。
public class Silo {
public boolean mixer,resistance;
public String state,mixerState,resState;
public Silo(boolean mix,boolean res){
mixer = mix;
resistance = res;
state = "empty";
}
}除了了解如何访问筒仓的状态变量之外,我还希望得到任何反馈和/或建议,说明如何更好地组织工作,以及我可能犯的任何错误。
发布于 2015-02-07 12:25:50
首先,Class#getDeclaredField(String)返回一个Field对象,而不是该字段的实际值。要获得值,必须使用Field#get(Object),其中参数是要访问字段的类的实例。在您的代码中,这将是:
LiqPlantSim sim = doSomethingToGetInstance();
f = LiqPlantSim.class.getDeclaredField("siloX");
Silo silo = (Silo) f.get(sim);这就引出了我的下一个观点:为什么要使用反射?您的答案可能与使用标签获得正确的Silo有关。您应该*重组LiqPlantSim以使用数组或List来解决这个问题:
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
public class LiqPlantSim{
private List<Silo> silos;
public Pipe pipe;
public LiqPlantSim(){
silos = new ArrayList<>();
silos.add(new Silo(false,false));
silos.add(new Silo(false,true));
silos.add(new Silo(true,false));
silos.add(new Silo(true,true));
pipe = new Pipe();
}
public Silo getSilo(int index) {
return silos.get(index);
}
//Possibly other methods to access silos
}(编辑:您应该对SimHandler__中的按钮进行同样的操作)
然后,在处理程序中,您可以访问这样的Silo:
public void actionPerformed(ActionEvent pushButton){
try {
int labelLength = label.length();
int index = Integer.parseInt(label.substring(labelLength - 1, labelLength));
Silo silo = doSomethingToGetLiqPlantSimInstance().getSilo(index);
silo.state = "full" //Note that it is good practice to use private fields and public getters and setters
} catch (NoSuchFieldException e) {
} catch (SecurityException e) {
}
System.out.println(label.split("")[2]);
}更好的方法是,将索引保存在构造函数中,这样您就不必每次都重新计算它。
*当然,这只是一个建议。
发布于 2015-02-07 12:02:38
这是:"silo"+label.split("")[1]将创建String siloS。要从label变量try:label.substring(1,2)获得数字
另外,您不需要将Frame f传递给myValveButton构造函数,您可以使用this.add(but0)将按钮直接添加到SimHandler中。
发布于 2015-02-07 12:04:16
为什么要在按钮类中实现操作侦听器?ValveButton不应该知道当它被点击时该做什么。
相反,您应该在SimHandler类中实现动作侦听器。实例化8 ValveButtons之后,可以在循环中添加动作侦听器。
无论如何,如果您真的需要使用反射解决方案,我将使用微小的PrivilegedAccessor框架进行重新注释。虽然建议只在单元测试中使用,但它在您的情况下可能是有用的。
https://stackoverflow.com/questions/28381668
复制相似问题