簡體   English   中英

無法將值分配給最終變量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM