작성
·
226
·
수정됨
0
ArrayList<String> a = new ArrayList<>();
a.add("1");
a.add("2");
a.add("3");
int[] arr = {1, 2, 3};
arr[0] = 4; // 가능
a.get(0) = "one"; // 불가능
위와 같이 배열도 ArrayList 객체도 모두 Reference type입니다. 배열에 대한 인덱스 접근은 r-value, l-value로 모두 기능할 수 있는데 ArrayList에 대한 get()은 r-value(값으로만 사용)로써만 기능하고 있습니다.
get()의 반환형이 E로 제네릭(객체)인데 read only로 취급되는건가요...?
get()으로 해당 위치를 참조하는게 아닌건가요?
해당 메모리가 아닌 메모리의 값을 꺼내오는건가요?
HashMap<String, String> h1 = new HashMap<>();
h1.put("1", "one");
h1.get("1") = "하나"; // 불가능
다른 컬렉션 프레임워크지만 동일한 문제입니다.
put(key, value)를 사용해 값을 저장하고 get(key)를 사용해 value를 가져올 때 get()으로 값을 바꿀 수는 없는 건가요?
HashMap<String, ArrayList<String>> hashMap = new HashMap<>();
hashMap.get(date).add(Obj); // 가능
이 경우에는 get()으로 참조한 메모리에 대해 다시 참조하여 메서드 사용이 가능했습니다. 이러한 동작이 get()으로 값을 반환하는 것이 아니라 객체 메모리에 접근한다고 생각했습니다.
위에 질문과 함께 조금 더 직관적인 질문 드립니다.
public static void main(String[] args) {
// Calendar calendar = new Calendar();
// calendar.run();
HashMap<String, String> h = new HashMap<>();
h.put("1", "before");
System.out.println(h.get("1").equals("1")); // 참조하여 메서드 동작 확인
h.get("1") = "after"; // 불가능 => 왜 안되는지?
String str = "before";
System.out.println(str.equals("before")); // 참조하여 메서드 동작 확인
System.out.println(str);
str = "after"; // 변경 가능 => 왜 되는지?
System.out.println(str);
}
위 코드에서 각각 get()과 참조 변수 자체로 접근하였습니다.
get()으로는 메서드까지는 접근이 가능하나 값 변경이 안되었고
참조변수는 메서드 접근은 물론 값 변경(엄밀히 말하면 참조 변경)까지 되었습니다.
이유가 궁금합니다.
감사합니다.
답변 2
0
0
get() 메서드의 경우는 컬렉션 요소의 값을 가져오는 기능을 합니다. help를 보시면 반환값이 <E> 인것을 보실 수 있는데 이는 그 값을 반환하겠다는 의미입니다. 반환된 값은 객체나 기본 테이터인 경우 그 값인데, 그 값에 무언가를 넣은다는것은 가능하지 않습니다. 마치 1 = 3; 과 같은 결과가 되는 것입니다. 따라서 값을 넣을때는 해당 메모리에 값이 대입되는 메서드를 사용하는 것이 맞습니다. 말씀하신대로 변수인 경우는 l-value와 r-value가 모두 가능하지만, 상수인 경우는 l-value가 안되는것과 같은 경우입니다.
감사합니다!
말씀하신 "반환된 값은 객체나 기본 테이터인 경우 그 값인데"의 부분에서 객체의 경우 내부적인 값은 객체 메모리 주소의 형태로 참조가 반환되는 것이고 primitive type인 경우 stack에 저장된 값 그 자체가 반환된다로 이해해도 괜찮을까요?
즉 C/C++ 기준으로 reference type인 경우 주소 상수가 반환되고 prmitive인 경우 값이 반환됨로 생각해도 될까요?
아! const 참조변수의 형태로 반환된다는 말씀이네요!
C++로 설명을 도와주시니 더 명확히 이해됐습니다! 감사합니다!