glenn-syj / more-effective-java

이펙티브 자바를 읽으며 자바를 더 효율적으로 공부합니다
4 stars 5 forks source link

[MEJ-004] clone 메서드의 존재 이유와 Arrays 클래스의 clone 메서드에 대해 #89

Open undeadtimo opened 5 months ago

undeadtimo commented 5 months ago

Based on: #77 by @FickleBoBo

FickleBoBo님이 작성하신 글 잘 읽었습니다.

항상 근본적인 궁금증에서 시작하여 뻗어나가는 방식을 보고 글을 깊게 읽는 법을 배워갑니다.

저 또한 처음에는 clone 메서드에 대한 존재의의에 대하여 의구심을 갖고 있었지만, FickleBoBo님의 말처럼 생성자를 통해 동일한 값을 넣어 같은 속성을 갖는 객체를 생성하는 대신 clone 메서드 하나로 생성자를 통해 일일히 속성을 지정해주어 객체를 생성하는 것과 같은 효과를 일으킬 수 있다면 그것만으로 가치가 있다고 생각이 들었습니다.

이는 프로그래머가 framework 를 사용하며 얻는 이점처럼 단순 실수로 발생하는 Human error들을 피할 수 있게 해주고, 불필요한 작업과정을 생략하도록 하여 시간을 절약할 수 있게 해주는 이득으로 설명할 수도 있을 것 같습니다.

예를 들어, 많은 속성들을 가지고 있기 때문에 생성자로 같은 속성을 갖는 객체를 만들기 위해 많은 작업시간을 요구하는 경우에는 clone 메서드가 작업효율을 크게 높여줄 것이라 기대되기 때문입니다.

물론, 본문에서 말하는 것처럼, clone 메서드의 일반 규약이 허술하기에, 제대로 동작하도록 만들기 위해서는 지켜야 할 사항이 많아 clone 메서드를 가볍게 다루어서는 안될 것입니다.

추가적으로 FickleBoBo님이 어려웠던 점으로 꼽은 것 중,

자바에서는 모든 것이 객체라는 말을 얼핏 들었던거 같아서 그럼 배열도 어떠한 class에서 구현하고 있고 해당 class가 clone 역시 구현하지 않을까 했는데 공식 문서에서는 Object class라고만 나와서 이에 대한 이해를 충분히 하기 어려웠다.

는 부분은 Arrays 클래스에서 clone을 구현하지 않고 있음을 말하는 것인지 궁금합니다.

오라클 공식 문서에서 Arrays 대한 내용을 살펴보면, 해당 Arrays 클래스는 Object 클래스를 상속받고 있고, Object 클래스로부터 clone 메서드를 상속받고 있음을 명시하고 있습니다.

오라클 공식 문서 : Arrays

따라서, FickleBoBo님이 생각한 것처럼 Arrays 클래스에서 clone 메서드를 상속받아 구현하고 있는 것 같습니다.

clone의 존재 이유와 FickleBoBo님이 작성하신 어려웠던 점에 대한 저의 생각이 적절하지 않은 부분이 있을시 알려주신다면 감사하겠습니다.

FickleBoBo commented 5 months ago

Human error에 대해서는 생각해보지 못해서 놓치고 있었는데 이미 구현된 framework를 사용했을 때 취할 수 있는 장점으로 큰 부분을 차지할 수 있겠다는 생각이 드는 답변이어서 감명 깊습니다.

본 글에서 어려웠던 점으로 꼽았던 배열을 어떠한 class에서 구현했는지에 대한 문장이 표현이 매끄럽지 못했던 것 같습니다.

자바에서 모든 것이 객체라면 해당 객체를 구현한 클래스가 존재하고 개발자가 구현한 class가 아닌데 사용하고 있는 객체가 있다면 이는 자바의 내장 클래스를 사용하는 것이라고 생각했었습니다. "Hello Java"라는 문자열 다룰 때 String str = "Hello java";처럼 변수?(인스턴스?) 앞에 해당 클래스를 명시해서 그동안 사용을 해왔다고 생각합니다. 그렇다면 int[] arr = {1, 2, 3}int[]라는 클래스를 사용한 것인가 혹은 int 클래스에 배열이라는([ ]) 자바만의 어떠한 기능이 추가된 것일까 그것도 아니면 int라는 클래스와 무관한 기능에 배열이라는 클래스와 무관한 기능이 합쳐진 것일까 이러한 의문이 들었습니다. clone()은 Object 클래스의 메서드로 이를 사용한다는 것은 Object 클래스를 상속 받았다는 것인데, 배열과 clone()의 관계는 어디서 맺어지는 것일까 찾아보다 어려움을 겪어서 저런 문장으로 서술했었습니다.

Arrays 클래스에 대해서도 짧게 생각했었는데, 배열을 선언할 때 Arrays 클래스를 import하지 않아서 Arrays 클래스는 아니구나 생각했었습니다. 하지만 Math 클래스도 import하지 않고 사용 가능하기도 하고, 얼핏 수업 때 import하지 않고도 사용 가능한 일부 기능들이 있었던 것으로 기억이 나서 이점은 잘못 생각한 것 같습니다.(실제로는 import하지만 개발자에게 보여지지 않는 걸로 알고 있습니다.)인텔리제이의 자동완성 기능에는 해당 클래스나 메서드가 어떤 패키지에 들어있는지 보여주는 기능이 있습니다.(이클립스도 동일한 것으로 알고 있습니다.)여기서 Math의 경우 java.lang으로 소속이 표시되나 int와 같은 경우 어떠한 표현도 없어서 이것이 정말 클래스와 무관해서인지 이 역시 개발자에게 보여주지 않는 것인지는 잘 모르겠습니다.

기본 타입과 참조형 타입에 대해서는 알고 있지만 자바 내부적으로는 어떻게 동작하는지에 무지해서 ChatGPT를 통해 인사이트를 얻고자 활용했습니다.(아래 답변)

해당 답변이 개념적으로 정확한 답변인지에 대한 검증이 필요하겠지만 이것이 맞다면 배열은 Object 클래스를 상속 받는 클래스의 인스턴스처럼 취급되므로 clone()메서드의 사용이 가능한 것으로 보입니다. 추가로 Arrays 클래스는 이러한 배열에 편의를 위한 다양한 메서드를 넣은 유틸리티 클래스로 배열이 객체처럼 취급되기에 사용가능한 것으로 보입니다. (자바에서는 모든 것이 객체라는 표현도 조금은 정정할 필요가 있을 것 같습니다)

참고 자료 : https://docs.oracle.com/javase/8/docs/api/ 참고 자료 : ChatGPT

undeadtimo commented 5 months ago

먼저 FickleBoBo님의 답변에 대해 감사드립니다.

FickleBoBo님이 어려웠던 점으로 배열에 대해 꼽으신 것을 보고, 가벼운 의문이라 생각하였으나, 심도있는 이해를 돕는 깊은 의문이었군요.

저 또한 막연하게 '자바는 객체 지향 언어', '자바의 모든 것은 객체'라는 말을 보고, 당연히 모든 것은 객체이며 각각의 클래스를 갖고 있으리라 생각하였습니다.

따라서, Arrays 클래스 또한 다른 것들과 비슷한 일반적인 클래스이며, Object 클래스를 상속받기 때문에 clone 메서드를 사용할 수 있는 것이라 여겼습니다.

그러나, Arrays 클래스는 배열을 사용할 수 있도록 다양한 메서드를 가지고 있는 유틸리티 클래스로서 '객체처럼 취급'된다는 것을 알게되어 좁은 시야에 갇혀있음을 깨닫게 되었습니다.

비록 해당 정보가 ChatGPT에서 가져온 것이나, 충분히 생각해볼만한 주제며 의외의 것을 알게해주어 좋은 기회가 되었습니다.

저 또한 기본 타입과 참조 타입, Arrays 클래스에 대한 정확한 개념과 원리를 지속적으로 탐구하여 추가적인 정보를 얻게된다면 공유하도록 하겠습니다.