这是我的代码:
public String getGPA() {
String gpa = null;
final String responseBody1;
new Thread(new Runnable(){
public void run()
{
try {
HttpGet httpGet_gpa = new HttpGet("https://somedomain.com" + getRegId() + "&format=P");
HttpResponse response = httpClient.execute(httpGet_gpa);
responseBody1 = EntityUtils.toString(response.getEntity());
} catch (ClientProtocolException cpe) {
// Ignore
} catch (IOException ioe) {
// Ignore
}
}
}).start();
Document gpa_doc = Jsoup.parse(responseBody1);
Element p = gpa_doc.select("p").first();
gpa = p.text().replace("Your overall GPA (Grade Point Average) to date is:", "");
return gpa;
}
我收到此错误:cannot assign a value to final variable responseBody1
。这是什么意思?我尝试删除最终修饰符,但它告诉我我需要让它最终,但是当我这样做时,我得到了那个错误。关于为什么会发生这种情况以及如何解决问题的任何线索?
答案 0 :(得分:1)
这是与匿名类相关的问题。由于Java的黑魔法创建了实例化类以将变量传递给内部类的环境的副本,因此必须将它们声明为final
。更改responseBody1
不会更改原始变量,而是更改它的本地引用(因为String
是不可变的,您将无法获得您的想法)。
您应该通过外部类的包装器或方法。
答案 1 :(得分:1)
如果创建实现接口的匿名类(例如Runnable
),则它访问的任何局部变量必须为final
,并且必须在该点确定它们的值。匿名类不允许以外部方法可以看到更改的方式更改这些变量。 (这是Java的一个特性;其他语言允许更改外部局部变量。)
我不推荐一个解决方案,因为它看起来像你的方法无论如何都不会起作用。您创建一个新线程并在其上使用start()
,看起来您希望此线程修改responseBody1
。但是您的方法会尝试使用responseBody1
的值。您无法判断线程是否已达到修改responseBody1
的程度,因为您没有做任何事情来等待线程或以任何方式与线程同步。关于设计的其他一些事情需要改变。
但是,一种可能的解决方案是定义一个包含String
成员的新类:
static class StringHolder {
String responseBody1;
}
然后创建一个new StringHolder
并为此分配一个final
局部变量。虽然无法更改对StringHolder
的引用,但线程仍可以更改responseBody1
成员。
答案 2 :(得分:0)
最终属性意味着您保证不修改变量。这就是您无法修改变量的原因。
如果你被迫使用决赛,那就太容易了:就这样做
String newString = responseBody1;
然后按照
修改newString编辑:
刚才意识到这不是你想要的。您可以使用将在匿名类中调用的函数
更新:
private static String responseBody1;
public String getGPA() {
new Thread(new Runnable(){
public void run()
{
fetchResponse();
}
}).start();
Document gpa_doc = Jsoup.parse(responseBody1);
Element p = gpa_doc.select("p").first();
gpa = p.text().replace("Your overall GPA (Grade Point Average) to date is:", "");
responseBody1 = null;
return gpa;
}
public static void fetchResponse(){
try {
HttpGet httpGet_gpa = new HttpGet("https://somedomain.com" + getRegId() + "&format=P");
HttpResponse response = httpClient.execute(httpGet_gpa);
responseBody1 = EntityUtils.toString(response.getEntity());
} catch (ClientProtocolException cpe) {
} catch (IOException ioe) {}
}
现在我不确定它是否必须是静态函数和静态responseBody1。但我猜是这样。