2016-07-12 5 views
0

私は2つのコレクションを格納してから、イベントリスナーを追加します(ここでラムダはありません - Java 7に固執する必要があります)。最終的なコレクションがまだ更新されるのはなぜですか?

// 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); 

     } 

    }); 

私はこれを最初にデバッグして、コレクションが正しくセットアップされました。コードはちょうど初期化されたので、オブジェクトは含まれていませんでした。

リスナーをデバッグすると(アイテムが選択されたためにイベントが発生しました)、私は混乱しました。ブール値debug1debug2は、コレクションselectedItemsunselectedItemsが項目の選択に従って更新されたため、両方とも真です。したがって、イベントソースコレクションには、宣言された最終コレクション(selectedItems,unselectedItems)と同じアイテムが含まれていました。

最終的に宣言された2つのコレクションをそのまま維持する必要はありませんか?

+8

'final'のようなものは、*変数*は、それが参照するオブジェクトを変更することができないではないことを、変更することはできないと述べています。 – RealSkeptic

+1

変数 'selectedItems'は' final'ですので、再割り当てはできません。しかし、それは 'コレクション'を '最終的なものにしません。 – SomeJavaGuy

+0

また、更新されていますか?どのセットにも空のセットが含まれているので、それらのセットが空の場合、それらのブール値は「真」になります。 – RealSkeptic

答えて

6

finalは、finalと宣言された変数は変更できず、finalのクラスは継承できないことを意味します。 プリミティブでないすべての変数はJavaでの参照です。つまり、オブジェクトのインスタンスを指すか、オブジェクトのインスタンスを参照しますが、オブジェクト自体ではありません。

は、あなたが参照していると、そのすべてのフィールドがfinalprivateであり、何のセッターを持っていないfinal classのインスタンスである不変オブジェクトと呼ばれます。

これが明確になることを望みます。

+0

実用的な観点からは、不変の 'Collection'が必要な場合は、[java.util.Collections.unmodifiableCollection(...)](https://docs.oracle.com/javase/8/docs/api)を使用してください。 /java/util/Collections.html#unmodifiableCollection-java.util.Collection-)メソッドを呼び出して、 'rri.getSelected()'と 'rri.getUnSelected()'コレクションをラップします。 –

2

finalを使用すると、その内容を更新できるかどうかではなく、別のオブジェクトを参照するように参照を変更することはできません。

あなたは変更不可能なセットを使用したい場合はCollections.unmodifiableSet(yourSet);

関連する問題