我有一个快速的问题,希望有人能回答。基本上,我有一个字符串变量,需要根据组合框中的值进行更改,其中有一个事件侦听器附加到它。然而,如果我使字符串最终,那么它不能改变,但如果我不使它最终,那么eclipse呻吟,它不是最终的。最好的(也是最简单的)解决方法是什么?
代码如下
final String dialogOutCome = "";
//create a listener for the combo box
Listener selection = new Listener() {
public void handleEvent(Event event) {
//get the value from the combo box
String comboVal = combo.getText();
switch (comboVal) {
case "A": dialogOutCome = "a";
case "B": dialogOutCome = "b";
case "C": dialogOutCome = "c";
case "D": dialogOutCome = "d";
}
}
};
你不能。
考虑一下:
- 只要在其中声明的方法运行,本地变量就存在。
- 一旦该方法调用结束(通常是因为该方法存在),该变量就会消失
- 侦听器可以(通常)活得更久
那么当方法已经返回并且侦听器试图修改局部变量时应该发生什么呢?
因为这个问题没有一个真正好的答案,他们决定不允许访问非final
局部变量,从而使这种情况不可能发生。
- 尝试更改字段而不是局部变量(这可能也更适合侦听器的生命周期)或
- 使用
final
局部变量,您可以更改内容(例如List
或String[]
与单个元素)。
这些答案都是在表面上告诉你如何让一个有缺陷的方法"起作用"。
真正的问题是您试图将传统的、同步的、"调用/返回"编码模式应用于不支持它的库。真正的答案是,当你等待的事件异步发生时,你想要做的事情在事件发生后也必须异步发生。理解Swing的事件驱动特性对于有效地使用它是至关重要的。
换句话说,考虑哪段代码将读取dialogOutCome
。会执行一些操作吗?如果是,则从处理程序(或作为处理程序的结果)执行该操作。
另一种方法是使用这种方法。
public class ReturnValueListener implements Listener {
private String dialogOutCome;
public void handleEvent(Event event) {
//get the value from the combo box
String comboVal = combo.getText();
switch (comboVal) {
case "A": dialogOutCome = " gay";
ase "B": dialogOutCome = " ugly";
case "C": dialogOutCome = " smelly";
case "D": dialogOutCome = " great";
}
}
public String getDialogOutCome() {
return dialogOutCome;
}
}
Listener selection = new ReturnValueListener();
//Set my listener somewhere,
....registerListener(selection);
//After my handleEvent is called
String dialogOutCome = selection.getDialogOutCome();
创建简单的StringWrapper
对象:
static class StringWrapper {
String value;
StringWrapper(String value) {
this.value = value;
}
}
并将其用于字段类型dialogOutCome
:
final StringWrapper dialogOutCome = new StringWrapper("");
Listener selection = new Listener() {
public void handleEvent(Event event) {
String comboVal = combo.getText();
switch (comboVal) {
case "A": dialogOutCome.value = " gay";
case "B": dialogOutCome.value = " ugly";
case "C": dialogOutCome.value = " smelly";
case "D": dialogOutCome.value = " great";
}
}
};
可以使用setter进行间接设置。这将消除最后的限制(因为您正在访问的字段是' This '而不是'dialogOutcome')。
String dialogOutCome = "";
void setOutcome(String value){
dialogOutCome = value;
}
//create a listener for the combo box
Listener selection = new Listener() {
public void handleEvent(Event event) {
//get the value from the combo box
String comboVal = combo.getText();
switch (comboVal) {
case "A": setOutcome(" gay");
case "B": setOutcome(" ugly");
case "C": setOutcome(" smelly");
case "D": setOutcome(" great");
}
}
};
变通方案:使用StringBuilder代替String
。当然,StringBuilder
不能在handleEvent
中被修改引用,但是我们可以调用它的方法。
final StringBuilder sb = new StringBuilder();
Listener selection = new Listener() {
public void handleEvent(Event event) {
...
switch (comboVal) {
case "A": sb.delete(0, sb.length()).append("a");
case "B": sb.delete(0, sb.length()).append("b");
...
}
}
};
...
System.out.println(sb.toString());
然后你可以得到字符串值StringBuilder.toString();
编辑:请提供投票否决这个答案的原因