2016-07-12 23 views
0

Ich habe diesen Code, wo ich zwei Sammlungen speichern und dann einen Event-Listener hinzufügen (kein Lambda hier - ich muss bei Java 7 bleiben;)).Warum wird eine letzte Sammlung noch aktualisiert?

// rri is a ReturnRequestInterface 
    final Collection<BigDecimal> selectedItems = rri.getSelected(); 
    final Collection<BigDecimal> unselectedItems = rri.getUnSelected(); 

    rri.addInformationChangeEventListener(new ComponentInformationChangeListener() { 

     @Override 
     public void informationChange(RequestChangeEvent event) { 

      ReturnRequestInterface source = (ReturnRequestInterface) event.getSource(); 
      boolean debug1 = source.getSelected().containsAll(selectedItems); 
      boolean debug2 = source.getUnSelected().containsAll(unselectedItems); 

     } 

    }); 

Ich habe dies zunächst debugged und die Sammlung wurde korrekt eingerichtet. Es enthielt keine Objekte, da der Code gerade initialisiert wurde.

Das Debuggen des Hörers (das Ereignis wurde ausgelöst, weil eine Elementauswahl vorgenommen wurde) hat mich verwirrt. Die Booleschen Werte debug1 und sind beide wahr, da die Auflistung selectedItems und unselectedItems entsprechend der Elementauswahl aktualisiert wurden. Die Ereignisquellensammlung enthielt also dieselben Elemente wie die deklarierten endgültigen Sammlungen (selectedItems, unselectedItems).

Müssen die beiden angemeldeten endgültigen Sammlungen nicht so bleiben wie sie sind?

+8

'final' sagt, dass die * variabel * kann nicht geändert werden, nicht, dass das Objekt, um es bezieht sich nicht geändert werden kann. – RealSkeptic

+1

Da die Variable 'selectedItems'' final' ist, kann sie nicht neu zugewiesen werden. Aber das macht deine "Sammlung" nicht endgültig. – SomeJavaGuy

+0

Sind Sie sicher, dass sie aktualisiert wurden? Jeder Satz enthält eine leere Menge, so dass diese Booleans "wahr" sind, wenn diese Sätze leer sind. – RealSkeptic

Antwort

6

final bedeutet einfach, dass eine Variable, die final erklärt wurde kann nicht geändert werden, und eine Klasse, die final ist, kann nicht geerbt werden. Alle Variablen, die nicht primitiv sind, sind Verweise in Java, was bedeutet, dass sie auf eine Instanz eines Objekts "zeigen" oder verweisen, aber selbst keine Objekte sind.

Worauf Sie Bezug nehmen, heißt ein unveränderliches Objekt, das eine Instanz eines final class ist, das alle seine Felder final und private ist und keine Setter hat.

hoffe dies hilft zu klären.

+0

Und aus praktischen Gründen, wenn Sie unveränderliche 'Sammlung' wollen, verwenden Sie [java.util.Collections.unmodifiableCollection (...)] (https://docs.oracle.com/javase/8/docs/api /java/util/Collections.html#unmodifiableCollection-java.util.Collection-) um die Sammlungen 'rri.getSelected()' und 'rri.getUnSelected()' zu umbrechen. –

2

Die Verwendung von final bedeutet nur, dass die Referenz nicht so geändert werden kann, dass sie auf ein anderes Objekt zeigt, nicht darauf, ob der Inhalt aktualisiert werden kann oder nicht.

Wenn Sie eine unveränderbare Set Verwendung so etwas wie Collections.unmodifiableSet(yourSet);