2014-11-14 6 views
1

여기 내 코드입니다 :이 오류를 받고 있어요최종 변수에 값을 할당 할 수 없습니다

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. 이것은 무엇을 의미 하는가? 나는 최종 수정자를 제거하려고 노력했으나 최종 결정을 내릴 필요가 있다고 알려주지 만, 나는 그 오류를 얻는다. 왜 이런 일이 일어나고 그것을 고치는 방법에 대한 단서가 있습니까?

답변

1

익명 클래스와 관련된 문제입니다. Java의 마술은 클래스가 내부 클래스에 변수를 전달하도록 인스턴스화 된 환경의 복사본을 생성하므로 final으로 선언해야합니다. responseBody1을 변경하면 원래 변수가 변경되지 않고 로컬 참조가 변경됩니다 (String은 변경 불가능하므로 생각하는 것을 얻을 수 없습니다).

외부 클래스의 래퍼 또는 메서드를 통과해야합니다.

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해야 할 경우 확실하지 않다 : 당신은 당신이

업데이트 익명 클래스를 호출하는 기능을 사용할 수 있습니다. 그러나 나는 그렇게 추측하고있다.

+0

'최종 수정'과 '정적 수정'의 차이점은 무엇입니까?또한'EntityUtils.toString'에 의해 일부 데이터가로드 된 후에'responseBody1'에 액세스해야합니다. 그러나 변수를 'final'로 설정해야하므로 데이터에 액세스 할 수 없으며 일단 최종으로 설정하면 어떤 데이터도로드 할 수 없으며 스레드 외부에서 읽을 수 없습니다. – SomeProgrammer123

+0

정적은 클래스에 하나의 변수 인스턴스 만 존재한다는 것을 의미합니다. 즉,이 클래스의 모든 객체는 동일한 변수에 액세스 할 수 있습니다. responseBody1에 대해서, 나는 나의 대답을 편집했다. try로 정적 함수를 만들고 run() 함수를 호출하십시오. – Gaktan

+0

@Gaktan이 정적 함수는 무엇을 할 것입니까? 'String'을 반환하면 스레드의 run() 메서드는 함수 결과에 무언가를 할당해야하며 문제를 해결하지 못했습니다. 아마도 솔루션을 시연하는 코드 예제를 게시해야합니다. – ajb

1

인터페이스를 구현하는 익명 클래스 (예 : Runnable)를 만드는 경우 액세스하는 로컬 변수는 모두 final이어야하며 해당 값은 해당 시점에서 결정되어야합니다. 익명 클래스는 외부 메소드가 변경 사항을 볼 수있는 방식으로 변수를 변경할 수 없습니다. (이 기능은 Java의 기능으로, 다른 언어를 사용하면 외부 로컬 변수를 변경할 수 있습니다.)

어쨌든 방법이 작동하지 않는 것처럼 보이기 때문에 해결책을 추천 할 수 없습니다. 새 스레드를 만들고 그것에 start()을 사용하면이 스레드가 responseBody1을 수정할 것으로 예상됩니다. 그러나 사용자의 방법은 responseBody1의 값을 사용합니다. 쓰레드가 어떤 지점에서 기다리거나 어떤 식 으로든 동기화 할 수 없으므로 쓰레드가 responseBody1을 수정하는 지점에 도착했는지 여부를 알 수 없습니다. 디자인에 관한 다른 것이 바뀌어야 할 것입니다.

static class StringHolder { 
    String responseBody1; 
} 

는 그때 new StringHolder를 생성하고 이에 대한 final 로컬 변수를 할당 :

그러나, 가능한 해결책은 String 부재를 포함하는 새로운 클래스를 정의하는 것이다. StringHolder에 대한 참조는 변경할 수 없지만 스레드에 의해 responseBody1 구성원은 계속 변경 될 수 있습니다.

관련 문제