2017-03-01 6 views
1

Warum folgendes erlaubt ist:final boolean [] vs final boolean innerhalb Runnable

final boolean [] success = new boolean[1]; 
    Thread httpThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      HTTPConnect httpConnect = new HTTPConnect(getContext()); 
      success[0] = false 
      ... 
      if (whatever) 
      success[0] = true; 

Aber die folgenden nicht?

final boolean success; 
    Thread httpThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      HTTPConnect httpConnect = new HTTPConnect(getContext()); 
      success = false 
      ... 
      if (whatever) 
      success = true; 

Ich beziehe mich auf die boolean success hier. Zuerst dachte ich, es wäre, weil eine lokale Deklaration den Umfang verlieren würde, während eine Deklaration auf dem Heap überleben würde, nachdem der Bereich beendet ist, aber das scheint nicht der Fall zu sein, da eine Deklaration wie final ArrayList<Foo> bar = new ArrayList<>() keinen Wert zugewiesen werden kann.

+1

Entfernen Sie alle unnötigen Teile aus Ihrem Code, fragen Sie, warum das nicht funktioniert: 'boolean Erfolg; success [0] = true; ' Die Antwort ist einfach: weil' success' ein einfacher boolescher Wert ist, kein Array. – Kiryl

+0

@Kiryl Es war ein Tippfehler, behoben. – ShrimpCrackers

Antwort

1

Da Sie den boolean Wert tatsächlich in ein Array einbinden, so dass Sie den Inhalt des Arrays ändern können, aber Sie nicht die Referenz der Variablen success selbst ändern.

Das gleiche Ergebnis konnte mit einem AtomicBoolean (oder AtomicReference im Allgemeinen) erhalten werden.

Das Problem der Variablen in anonymen inneren Klassen geändert entsteht in dem folgenden Szenario wird erlaubt Dieses

boolean success; 
Thread httpThread = new Thread(new Runnable() { 
    @Override 
    public void run() { 
    success = false; 
    .... 

nicht, weil Sie Ändern sind, was success sich bezieht. Wenn Sie einen boolean[] verwenden, dann ändern Sie nicht, was success ist, sondern nur einen Wert, der in dem Objekt enthalten ist, auf das verwiesen wird, so dass es keine Probleme gibt.

1

Zunächst einmal hat Ihr zweites Beispiel ein paar Tippfehler: Da success ein boolean ist, sollten die Zuweisungsanweisungen nicht indiziert werden.

Ich nehme an, dass in beiden Fällen success eine lokale Variable ist. Wenn es ein Feld ist, dann können Sie einfach die final eliminieren und der zweite Fall wird funktionieren (nach dem Entfernen der Indizes).

Der Grund, warum der zweite Ansatz für eine lokale Variable nicht funktioniert, ist, dass Sie eine final Variable nicht zuweisen können, nachdem sie zugewiesen wurde. Die Geschichte ist für ein Array etwas anders: Sie können success immer noch kein neues Array zuweisen, aber Sie können Elementen des Arrays neue Werte zuweisen. Deshalb funktioniert der erste Ansatz. Ein Array wie dieses zu verwenden, ist ein übliches Idiom, um sowohl mit diesem Problem als auch mit dem Problem umzugehen, dass Java-Methoden keine "Out" -Argumente haben.