본문 바로가기
📔개발자 일기 | | TIL

[20220509] 개발자 일기 & TIL

by 캔 2022. 5. 9.

 

자바든 스프링이든 그 외 프로그래밍 언어든 공식 문서나 전문가가 쓴 책이나 강의 기반으로 공부할 필요가 있는 것 같다. 인터넷 상의 글이나 블로그 포스팅은 읽으면서 끊임없이 의심해야 한다. 그들도 잘못된 지식을 기반으로 글을 썼을 수도 있고 이해를 하는 도중 잘못 이해하거나 글을 쓰다가 실수로 잘못 설명하는 경우가 있을 수 있기 때문이다.

 

IDE에서 Ctrl로 라이브러리 객체들을 돌아다니면서 자바독과 코드를 살펴보는 것도 좋은 학습 방법인 것 같다. 사실, 자바독이 결국 공식 문서이고, 그 바로 아래 코드 예제가 있으니 이만한 교재가 있을 리 만무하다. 다만, 99%가 영어로 이루어져 있다는 게 제일 큰 단점이긴 하지만 말이다.

 

TIL

지난번에 String과 Entity의 equals(), hashCode()를 따로 다루면서 두 객체의 공통점을 정리하지 않은 것 같은데, 이 둘은 자바의 기본 객체 취급 방식을 무시(override)한다는 점이다.

 

Object의 equals() 메서드를 살펴보면 다음과 같다.

public boolean equals(Object obj) {
    return (this == obj);
}

 

Object는 모든 객체의 수퍼 클래스, 즉 최상위 객체이다. 그러다 보니 객체를 비교할 때 상속받은 equals() 메서드를 사용한다는 것은 자바의 기본 비교 전략을 따른다는 것이고, 이 말은 즉 위 코드처럼 '==' 연산자를 사용해 다른 객체와 같은지 비교한다는 말이다. 여기서 알아야 할 것은 '=='이 어떻게 객체를 비교하는가 하는 것이다. 두 객체에 '==' 연산자를 사용하게 되면, 각각의 객체의 메모리 주솟값이 같은지를 비교한다. 다시 말해, A와 B라는 인스턴스가 존재하면 A와 B가 같은 메모리 주소를 가리키고 있는지 여부를 판단하게 된다는 것이다.

 

자바에서 객체를 사용할 때는 일반적으로 new라는 예약어를 사용한다. 이름에서 알 수 있듯이 new 예약어를 사용하면 지금까지 생성된 객체들과는 별개로 새로운 객체가 탄생하게 된다. 즉 새로 생성된 객체들은 계속해서 서로 다른 메모리 주소에 할당되는 것이다. 이런 상황에서 객체를 비교할 때 equals()를 사용하면 객체의 주솟값이 같은지 비교하므로 항상 동일하지 않게 된다. 만약에 객체의 구성이(멤버 변수나 메서드) 똑같다고 하더라도 새로 생성된 객체는 메모리의 서로 다른 곳을 가리키게 되고 비교했을 때 같지 않다는 결과를 얻는다.

 

이런 자바의 비교 전략은 객체의 구성이나 그 값이 같으면 동일성을 보장해야 하는 경우에 적절하지 않을 수 있다. 그 경우가 바로 자바의 String과 JPA의 @Entity 객체이다. String의 경우 굉장히 큰 문자열이 들어갈 수도 있고 애플리케이션 내에서 자주 사용되는 참조형 변수이다. 그렇기 때문에 만약에 String이 생성될 때마다 메모리의 다른 부분을 가리키면 비효율적일 수 있다. 만약 str1과 str2라는 String 객체가 있는데 값이 "ABC"로 동일하다고 하자. 같은 "ABC"라는 값을 가지면서도 메모리의 공간을 두 번 차지하게 된다. 이런 메모리 낭비를 막기 위해 String의 값들은 Heap 메모리의 String Constant Pool에서 값을 기준으로 관리되고, String의 equals는 Object의 equals() 메서드를 오버라이드하여 '==' 연산뿐만 아니라 값이 같은지도 비교하게 된다. 

 

JPA의 @Entity 객체도 마찬가지다. 같은 테이블에서 id가 같은 항목을 검색하여 같은 로우를 각각 담게 된 엔티티 객체들은 객체의 비교가 아니라 값 비교가 메모리 공간을 좀 더 효율적으로 사용할 수 있게 된다.

'📔개발자 일기 | | TIL' 카테고리의 다른 글

[20220511] 개발자 일기 & TIL  (0) 2022.05.11
[20220510] TIL  (0) 2022.05.10
[20220505] TIL  (0) 2022.05.05
[20220504] 개발자 일기 & TIL  (0) 2022.05.04
[20220502] 개발자 일기 & TIL  (0) 2022.05.02