2017-12-23 6 views
0

Java (Android Studio)에서 이와 같은 기괴한 동작이 발생합니다. 내가 해왔 던 것은 String의 ArrayList를 일부 데이터로 채우는 것이다. 그런 다음 해당 ArrayList를 사용하여 객체를 인스턴스화하면 새 객체가 객체 유형의 다른 ArrayList에 추가됩니다. ArrayList를 지우면 클래스 생성자에 전달 된이 ArrayList의 데이터도 지워집니다.

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

그런 다음 활동에, 나는 두 ArrayLists, 하나 개라는 언어와 하나라는 사람을 사용 : 여기

는 클래스의 생성자입니다. 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 언어를 지워야하므로 다시 사용할 수 있습니다.

실제로 일어난 일을 테스트하기 위해 첫 번째 로그에 추가 된 언어가 표시된다는 사실을 알았습니다 (언어가 아닌 Person에서 언어가 제공됨을 알 수 있음). 그러나 두 번째 로그는 langauges 배열 IN Person 클래스가 비어있는 (지워진) 예외를 생성합니다. 명확한 기능으로 인해 언어 배열뿐만 아니라 Person 클래스의 언어 배열을 지우는 원인이 될 수 있습니까?

+0

ArrayList에 대한 참조를 멤버 변수로 저장 한 객체에 전달합니다. Person.languages ​​객체는 원래 ArrayList와 동일한 데이터를 참조합니다. 이를 방지하려면 데이터를 복제하기 위해 copy 메서드를 호출하고 새 Object를 새로 만들어야합니다. – Zachary

+0

@ Zachary 나는 문자 그대로 자바가 가치에 의한 언어라고 생각했다. 나는이 문제를 해결했다. 내가 올바른 것으로 선택할 수 있도록 질문에 대답 할 수 있습니까? – Amine

답변

1

Person 클래스의 생성자를 호출하면 언어 ArrayList 객체에 대한 참조를 전달합니다. 동일한 메모리 조각에 대한 참조입니다. 참조를 사용하여 메서드를 호출하거나 변수를 변경하면 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. 
}