[java] Cloneable이 더 이상 사용되지 않는 이유는 무엇입니까?

CloneableJava의 인터페이스가 손상 되었다는 것이 일반적으로 이해 됩니다. 여기에는 여러 가지 이유가 있지만 언급하지 않겠습니다. 다른 사람들은 이미 그것을했습니다. 또한 Java 설계자 자신 의 위치이기도합니다 .

따라서 내 질문은 : 왜 아직 폐기되지 않았습니까? 핵심 Java 팀이 중단되었다고 판단한 경우 사용 중단을 고려해야합니다. 그렇게 하지 않은 이유는 무엇입니까 (Java 8에서는 더 이상 사용되지 않습니다 )?



답변

버그 로 1997 년에 제출 된 자바 버그 데이터베이스에 추가하는 방법에 대한 clone()메서드에 Cloneable더 이상 쓸모가 없을 것이다, 그래서는. 그것은 “수정하지 않을 것”이라는 결의안으로 마감되었으며 정당화는 다음과 같습니다.

Sun의 TRC (Technical Review Committee)는이 문제를 오랫동안 고려 하여 현재 Cloneable 인터페이스의 문서를 개선하는 것 이외의 조치 를 취하지 않는 것이 좋습니다 . 권장 사항은 다음과 같습니다.

기존 Java 객체 복제 API에 문제가 있습니다. java.lang.Object에 보호 된 “복제”메소드가 있으며 인터페이스 java.lang.Cloneable이 있습니다. 다른 사람들이 클래스를 복제 할 수있게하려면 클래스가 Cloneable 인터페이스를 지원하고 공용 복제 방법으로 기본 보호 된 복제 방법을 재정의해야합니다. 불행하게도, 안개 속에서 편리하게 잃어버린 이유로 Cloneable 인터페이스는 복제 방법을 정의하지 않습니다.

이 조합은 상당한 양의 혼란을 초래합니다. 일부 클래스는 Cloneable을 지원한다고 주장하지만 실수로 clone 메소드를 지원하는 것을 잊어 버립니다. 개발자는 Cloneable의 작동 방식과 클론의 작동 방식에 대해 혼란스러워합니다.

불행하게도, “복제”방법을 Cloneable에 추가하는 것은 호환되지 않는 변경이 될 것입니다. 이진 호환성을 깨뜨리지는 않지만 소스 호환성을 깨뜨릴 것입니다. 일화 적 증거에 따르면 실제로 클래스가 Cloneable 인터페이스를 지원하지만 공용 클론 메소드를 제공하지 못하는 경우가 많이 있습니다. 토론 후에 TRC는 만장일치로 호환성 영향으로 인해 기존 Cloneable 인터페이스를 수정하지 말 것을 권장했습니다.

대체 제안은 원래 의도 된 Cloneable 목적을 반영하기 위해 새 인터페이스 java.lang.PubliclyCloneable을 추가하는 것이 었습니다. TRC는 5 ~ 2의 다수로 이에 대해 권장했습니다. 주된 관심사는 이것이 이미 혼란 스러워진 그림에 더 많은 혼동 (맞춤법 혼동 포함)을 추가 할 것이라는 점이었습니다.

TRC는 만장일치로 기존 Cloneable 인터페이스추가 문서를 추가하여 사용 방법을보다 잘 설명하고 구현자를위한 “모범 사례”를 설명 할 것을 권장했습니다.

따라서 이것은 사용 중단 에 대한 직접적인 내용은 아니지만 Cloneable을 “사용 중단”하지 않는 이유는 Technical Review Comitee가 기존 문서수정하는 것이이 인터페이스를 유용하게 만들기에 충분하다고 판단했기 때문 입니다. 그리고 그들은 그렇게했습니다. Java 1.4까지는 Cloneable다음과 같이 문서화되었습니다.

클래스는 Cloneable 인터페이스를 구현하여 Object.clone () 메소드에 해당 메소드가 해당 클래스의 인스턴스에 대한 필드 필드 사본을 작성하는 것이 합법적임을 표시합니다.

Cloneable 인터페이스를 구현하지 않은 인스턴스를 복제하려고하면 예외 CloneNotSupportedException이 발생합니다.

Cloneable 인터페이스는 메소드를 선언하지 않습니다.

2002 년 2 월에 릴리스 된 Java 1.4 (현재 버전) (Java 8)부터 다음과 같습니다.

클래스는 Cloneable 인터페이스를 구현하여 Object.clone () 메소드에 해당 메소드가 해당 클래스의 인스턴스에 대한 필드 필드 사본을 작성하는 것이 합법적임을 표시합니다. Cloneable 인터페이스를 구현하지 않는 인스턴스에서 Object의 clone 메소드를 호출하면 CloneNotSupportedException 예외가 발생합니다.

일반적으로이 인터페이스를 구현하는 클래스는 공용 메소드로 Object.clone (보호 된)을 대체해야합니다. 이 메서드를 재정의하는 방법에 대한 자세한 내용은 Object.clone ()을 참조하십시오.

이 인터페이스에는 clone 메소드가 포함되어 있지 않습니다. 따라서이 인터페이스를 구현한다는 사실만으로 개체를 복제 할 수 없습니다. clone 메소드가 반사적으로 호출 되더라도 성공할 것이라는 보장은 없습니다.


답변

“왜 Cloneable더 이상 사용되지 않습니까?”에 대한 짧은 대답 (또는 실제로 X더 이상 사용 되지 않는 이유는) 더 이상 사용되지 X않도록주의를 기울이지 않았다는 것입니다.

더 이상 사용되지 않는 대부분의 항목은 제거 할 특정 계획이 있으므로 더 이상 사용되지 않습니다. 예를 들어, Java SE 9에서는 LogManager의 메소드 addPropertyChangeListenerremovePropertyChangeListener메소드가 Java SE 8 에서 제거 되기 위해 더 이상 사용되지 않습니다. 그 이유는 모듈 상호 종속성이 불필요하게 복잡하기 때문입니다. 실제로 이러한 API는 JDK 9 초기 개발 에서 이미 제거 되었습니다. 빌드합니다. (유사한 속성 변경 리스너 호출도 제거되었습니다 ( JDK-8029806 참조 ).Pack200

그런 유사한 계획에 대한에 존재하지 않는 CloneableObject.clone().

더 긴 답변에는 이러한 API에 발생할 것으로 예상되는 사항, 더 이상 사용되지 않는 플랫폼에 어떤 비용 또는 이점이 발생하는지, API가 더 이상 사용되지 않을 때 개발자에게 전달되는 내용과 같은 추가 질문에 대해 논의해야합니다. 최근 JavaOne 토론 Debt and Deprecation 에서이 주제를 살펴 보았습니다 . (이 링크에서 제공되는 슬라이드; 여기 비디오 ) JDK 자체는 사용 중단에있어 일관성이없는 것으로 나타났습니다. 예를 들어 다음과 같은 여러 가지 다른 의미로 사용되었습니다.

  • 이것은 위험하며 당신은 그것을 사용의 위험을 알고 있어야합니다 (예를 Thread.stop(), Thread.resume()Thread.suspend()).

  • 향후 릴리스에서 제거 될 예정입니다.

  • 이것은 더 이상 사용되지 않으며 다른 것을 사용하는 것이 좋습니다 (예 :의 많은 메소드 java.util.Date)

이 모든 것들은 별개의 의미이며, 다른 부분 집합은 더 이상 사용되지 않는 다른 것에 적용됩니다. 그리고 그들 중 일부는 더 이상 사용되지 않는 것들에 적용됩니다 (그러나 더 이상 사용되지 않아야 할 수도 있습니다).

Cloneable그리고 Object.clone()그들이 설계 결함을 가지고 올바르게 사용하기 불편하다는 의미에서 “깨진”입니다. 그러나 clone()여전히 배열을 복사하는 가장 좋은 방법이며 복제에는 신중하게 구현 된 클래스 인스턴스의 복사본을 만드는 데 약간의 유용성이 있습니다. 복제를 제거하면 호환되지 않는 변경으로 인해 많은 문제가 발생합니다. 복제 작업은 다른 방식으로 다시 구현 될 수 있지만 아마도 속도가 느릴 수 있습니다 Object.clone().

그러나 대부분의 경우 복제본보다 사본 생성자가 선호됩니다. 따라서 Cloneable“사용되지 않음”또는 “대체 됨”또는 이와 유사한 것으로 표시하는 것이 적절합니다. 이것은 개발자들에게 아마도 다른 곳을보고 싶다고 말하지만, 이후 릴리스에서 복제 메커니즘이 제거 될 것이라는 신호는 아닙니다. 불행히도, 그러한 마커는 존재하지 않습니다.

상황이 잘 드러나면서, “더 이상 사용되지 않음”은 사용되지 않는 기능이 거의 사라 졌음에도 불구하고 궁극적 인 제거를 의미하는 것으로 보이므로 사용 중단이 복제 메커니즘에 대해 보증되지 않는 것 같습니다. 아마도 미래에는 개발자가 대체 메커니즘을 대신 사용하도록하는 대체 표시를 적용 할 수 있습니다.

최신 정보

버그 보고서 에 몇 가지 추가 기록을 추가했습니다 . 초기 JVM 구현 자이자 JVM 스펙의 공동 저자 인 Frank Yellin은 다른 답변 에서 인용 된 TRC 권장 사항의 “미시간에 잃어버린”주석에 대한 응답으로 일부 주석을 작성했습니다 . 여기에 관련 부분을 인용했습니다. 전체 메시지는 버그 보고서에 있습니다.

Cloneable에는 Serializable과 달리 동일한 방법이 없습니다. Cloneable은 클래스가 지원하는 메서드에 대해 구체적으로 말하지 않고 클래스의 속성을 나타냅니다.

반영하기 전에, 우리는 객체의 얕은 사본을 만들기위한 기본 방법이 필요했습니다. 따라서 Object.clone ()이 탄생했습니다. 또한 많은 클래스가이 메소드를 재정의하고 모든 클래스를 복제하려는 것은 아니라는 것이 분명했습니다. 따라서 Cloneable은 프로그래머의 의도를 나타 내기 위해 탄생했습니다.

요컨대 Cloneable의 목적은 공용 clone () 메소드가 있음을 나타 내기위한 것이 아닙니다. Object.clone ()을 사용하여 복제 할 의사가 있음을 나타 내기 위해 clone ()을 공개할지 여부를 결정하는 것은 구현에 달려 있습니다.


답변

왜 더 이상 사용되지 않습니까?

JCP는 그렇게하기에 적합하지 않았기 때문에 결코 그렇게하지 않을 수 있습니다. 그들에게 묻다. 당신은 잘못된 곳에서 묻고 있습니다.

Java API 에서이 일을 유지하는 이유는 무엇입니까

이전 버전과의 호환성 요구 사항으로 인해 아무도 Java API에서 아무것도 제거하지 않습니다. 마지막으로 발생한 것은 1996/7 년 1.0과 1.1 사이의 AWT 이벤트 모델 변경이었습니다.


답변