[英]Cannot assign a value to final variable
這是我的代碼:
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
。 這是什么意思? 我嘗試刪除了final修飾符,但它告訴我需要將其修飾為final,但是當我這樣做時,我會收到該錯誤。 關於為什么發生這種情況以及如何解決的任何線索?
那是與匿名類有關的問題。 由於Java的黑魔法創建了環境的副本,在該環境中實例化了類以將變量傳遞給內部類,因此必須將它們聲明為final
。 更改responseBody1
不會更改原始變量,但會更改它的本地引用(並且由於String
是不可變的,因此您將無法獲得您的想法)。
您應該通過外部類的包裝器或方法。
如果創建實現接口的匿名類(例如Runnable
),則它訪問的任何局部變量都必須是final
,並且必須在該點確定它們的值。 不允許匿名類以外部方法可以看到更改的方式更改這些變量。 (這是Java的功能;其他語言允許更改外部局部變量。)
我不推薦一種解決方案,因為在我看來,您的方法還是行不通的。 您創建了一個新線程並在其上使用start()
,看起來您希望該線程修改responseBody1
。 但是您的方法然后嘗試使用responseBody1
的值。 您無法確定線程是否到達修改responseBody1
的地步,因為您不做任何事情來等待線程或以任何方式與其同步。 有關設計的其他內容將需要更改。
但是,可能的解決方案是定義一個包含String
成員的新類:
static class StringHolder {
String responseBody1;
}
然后創建一個new StringHolder
並為其分配final
局部變量。 盡管無法更改對StringHolder
的引用,但該線程仍可以更改responseBody1
成員。
final屬性表示您保證不修改變量。 這就是為什么您不能修改變量的原因。
如果您被迫使用決賽,那將非常簡單:只需這樣做
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。 但是我猜是這樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.