2017-12-23 4 views
0

Java(Android Studio)ではこのような奇妙な動作に直面しています。私がやっていることは、StringListのArrayListにデータを取り込むことです。その後、そのArrayListを使用してオブジェクトをインスタンス化すると、新しいオブジェクトがオブジェクト型の別のArrayListに追加されます。ここでArrayListを消去すると、クラスコンストラクタに渡されたこのArrayListからのデータもクリアされます。

は、クラスのコンストラクタです:

protected ArrayList<String> languages; 
    public Person(ArrayList<String> languages) 
    { 
     this.languages=languages; 
    } 

は、その後の活動で、私は2つのArrayList、と呼ばれる1つの言語と1と呼ばれる者を使用しています。言語ArrayListは、Personsに追加された新しいオブジェクトに渡されます。

ArrayList<String> languages=new ArrayList<String>(); 
ArrayList<Person> Persons=new ArrayList<Person>(); 

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main_layout); 
     . 
     . 
     . 
     . 
     . 
     . 
       english=(CheckBox)findViewById(R.id.english); 
       if(anglais.isChecked()) 
        languages.add(english.getText().toString()); 
       Persons.add(new Person(languages)); 
       Log.i("test: ",Persons.get(0).getLangues().get(0)); // Will show English 
       languages.clear(); // Here I clear the languages ArrayList so I can add new languages for another person 
       Log.i("test: ",Persons.get(0).getLangues().get(0)); // Produces an exception. 
      } 
     }); 
    } 

ご覧のとおり、まず言語を設定してから、Personsに言語を使用して新しいオブジェクトを設定します。異なる言語の別の人物を追加するには(たとえば)、ArrayList言語をクリアして再利用できるようにしなければなりません。

実際に何が起こったかをテストするために、最初のログに追加された言語が表示されることが分かりました(言語からPersonsから言語を取得していることに注意してください)。ただし、2番目のログでは、langauges配列のIN Personクラスが空(クリア)であるという例外が生成されます。何が、言語クラスをクリアするだけでなく、Personクラスの言語配列をクリアすることができないのでしょうか?

+0

ArrayListへの参照を、メンバ変数として保存するオブジェクトに渡しています。 Person.languagesオブジェクトは元のArrayListと同じデータを参照します。これを避けるには、新しい別個のオブジェクトを作成しながら、データを複製するためにcopyメソッドを呼び出す必要があります。 – Zachary

+0

@ Zachary私は文字通りJavaは価値ある言語だと思っていました。私はこの問題を解決しました。質問に答えることができますので、私は正しいものとして選ぶことができますか? – Amine

答えて

1

Personクラスのコンストラクタを呼び出すと、言語ArrayListオブジェクトへの参照が渡されます。同じメモリへの参照。参照の1つを使用してメソッドを呼び出すか変数を変更すると、Object自体が変更されます。つまり、そのObjectへのすべての参照も変更されます。これをよりよく理解するには、変数の仕組みを理解する必要があります。 Javaでは、変数はメモリのチャンクへの参照です。このメモリに複数の参照があるかもしれません。

public static void main(String args[]) { 
    ArrayList<String> list = new ArrayList<>(); 
    ArrayList<String> newReference; 
    list.add("String1"); 
    list.add("String2"); 
    list.add("String3"); 
    newReference = list; 
    newReference.remove(0); // This will remove the item in the first index of the object. This will remove from both list and newReference as they are currently referencing the same object. 
    newReference = list.clone(); 
    newReference.remove(0); // This will remove the item in the first index of the object referenced by newReference. It is not the same as that of list as you have cloned the data to a new segment of memory. 
} 
関連する問題