clone() 메서드가 java.lang으로 보호되는 이유는 무엇입니까?오브젝트?
에서 보호되고 있다고 정의되어 있는 구체적인 이유는 무엇입니까?java.lang.Object
되고 있다는 스럽다. 이 보호되고 있다는 스럽다.clone
않습니다.Cloneable
인터페이스입니다.
다음과 같이 말할 수 없기 때문에 데이터 복사에는 이 방법을 사용할 수 없습니다.
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
Cloneable
현재는 주로 오류로 간주되고 있습니다(아래 참조).통상, 인터페이스의 실장을 실시할 수 있으면 좋겠다고 생각하고 있습니다.Cloneable
그러나 반드시 인터페이스를 만들 필요는 없습니다(의 사용법과 유사).Serializable
반영이 없으면 이 작업을 수행할 수 없습니다.
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Josh Bloch의 효과적인 Java에서 인용:
「클론 가능 인터페이스는, 오브젝트가 복제를 허가하고 있는 것을 어드버타이즈 하기 위한, 믹스인 인터페이스로서 의도되어 있습니다.유감스럽게도 이 목적을 달성하지 못합니다...이는 매우 비정상적인 인터페이스 사용으로 에뮬레이트되는 인터페이스가 아닙니다.인터페이스를 구현하여 클래스에 영향을 미치려면 해당 인터페이스와 그 모든 슈퍼클래스가 상당히 복잡하고 강제할 수 없으며 대부분 문서화되어 있지 않은 프로토콜을 따라야 합니다.
Clonable 인터페이스는 클래스가 클론을 지원할 수 있음을 나타내는 마커일 뿐입니다.메서드는 개체를 호출하면 안 되고 공용으로 재정의할 수 있으므로 보호됩니다.
송신원 Sun:
class Object에서 clone() 메서드는 protected로 선언됩니다.Cloneable 구현만 하면 동일한 패키지의 서브클래스와 멤버만 오브젝트에서 clone()을 호출할 수 있습니다.패키지 내의 임의의 클래스가 clone() 메서드에 액세스할 수 있도록 하려면 다음과 같이 클래스가 덮어쓰고 공개임을 선언해야 합니다.(메서드를 덮어쓰면, 보다 프라이빗하게는 할 수 없지만, 보다 프라이빗하게는 할 수 없습니다.여기서는 오브젝트의 보호된 clone() 메서드가 퍼블릭메서드로 덮어씁니다).
clone
현재 계층에 고유하도록 재정의해야 하기 때문에 보호됩니다.하지만, 공개 작성은 합니다.clone
오브젝트를 복제하는 메서드는 오브젝트를 필요로 하는 클래스용으로 특별히 작성된 메서드만큼 좋지 않습니다.
복제 메서드는 어떤 개체에서도 직접 사용할 수 없기 때문에 하위 클래스에서 재정의됩니다.
물론 그것은 공개될 수 있고 복제가 불가능할 때 적절한 예외를 둘 수도 있지만, 나는 그것이 오해를 불러일으킬 것이라고 생각한다.
지금 당장 클론이 구현되는 방식을 보면 클론을 사용하는 이유와 오브젝트의 클론 작성 방법을 생각할 수 있습니다.
IMHO는 이렇게 간단합니다.
#clone
개체에서는 할 수 .#clone
로 호출해야 .Object
class의 를 취득할 수 .
서브클래스로 호출할 수 있지만 다른 클래스로 호출할 수 없는 메서드의 올바른 범위는 무엇입니까?
입니다.protected
.
「」를 Cloneable
물론 다른 수업에서 호출할 수 있도록 이 방법을 공개합니다.
기본 구현에서는 모든 필드(프라이빗 포함)의 얕은 구성원별 복사가 수행되므로 이 기능이 보호됩니다.이것은 처음부터 오브젝트가 처리하도록 설계된 것이 아닙니다(예를 들어 공유 목록에서 생성된 오브젝트인스턴스를 추적하는 등).
" " " " 。clone()
.Cloneable
이 작업은 잠재적으로 안전하지 않은 작업이며 광범위한 결과를 초래할 수 있습니다. 따라서 이 강의의 작성자는 명시적으로 동의해야 합니다.
클론 가능의 자바독에서.
* By convention, classes that implement this interface (cloneable) should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {@link java.lang.Object#clone()} for details on overriding this
* method.
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
따라서 모든 개체에 대해 클론을 호출할 수 있지만 대부분의 경우 원하는 결과나 예외가 없습니다.그러나 이는 복제 가능 기능을 구현하는 경우에만 권장됩니다.
Clone() 메서드는 내부적으로 '복제 가능 여부' 체크가 있습니다.이렇게 하면 Java 팀은 clone() method의 부적절한 사용을 제한할 수 있다고 생각할 수 있습니다.clone() 메서드는 서브클래스에 의해서만 보호됩니다.오브젝트는 모든 서브클래스의 부모 클래스이기 때문에 위의 '클론 가능 인스턴스' 체크가 없으면 Clone() 메서드를 모든 클래스에서 사용할 수 있습니다.이것이 Java 팀이 clone() 메서드의 체크에 의해 clone()의 부적절한 사용을 제한한다고 생각하는 이유입니다.
따라서 클론 가능 클래스가 구현되어 있는 모든 클래스는 오브젝트 클래스의 clone() 메서드를 사용할 수 있습니다.
또한 보호되므로 복제 가능한 인터페이스를 구현하는 하위 클래스에서만 사용할 수 있습니다.공개하려면 이 메서드는 서브클래스에 의해 자체 구현으로 덮어써야 합니다.
네, 제가 만났던 것과 같은 문제입니다.하지만 나는 이 코드를 구현함으로써 그것을 해결한다.
public class Side implements Cloneable {
public Side clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
}
return side;
}
}
아까 누가 말한 것처럼.
또한 Sun 개발자는 인간일 뿐이며, ArrayList에서 기능하지 않는 클론 방법을 구현한 것과 같은 실수를 했습니다.따라서 일반적으로 클론 방식에 대해 경험이 풍부한 Java 프로그래머들도 훨씬 더 깊은 오해를 가지고 있습니다.
그러나 최근에 구축 방법이나 내용을 불문하고 모든 콘텐츠를 포함하는 개체를 빠르고 쉽게 복사할 수 있는 솔루션을 발견했습니다.이 답변은 다음과 같습니다.Bug in using Object.clone()
Java JDK 프레임워크는 다음과 같은 훌륭한 사고를 보여줍니다.
복제 가능한 인터페이스는 속성에 가깝기 때문에 "public T clone();" 메서드는 포함되어 있지 않습니다.Serialable)을 사용하여 인스턴스를 복제할 수 있습니다.
다음과 같은 이유로 이 설계에는 문제가 없습니다.
Object.clone()은 사용자 정의 클래스에서 원하는 작업을 수행하지 않습니다.
Myclass 구현의 경우 Clone()을 "public MyClass clone()"로 덮어씁니다.
MyInterface 확장 복제 가능 및 MyInterface를 구현하는 MyClass가 있는 경우: 인터페이스에서 "public MyInterface clone();"을 정의하기만 하면 MyInterface 개체를 사용하는 모든 메서드는 MyClass 클래스에 관계없이 이들을 복제할 수 있습니다.
언급URL : https://stackoverflow.com/questions/1138769/why-is-the-clone-method-protected-in-java-lang-object
'it-source' 카테고리의 다른 글
bind_result vs get_result를 사용하는 방법의 예 (0) | 2022.11.19 |
---|---|
regex의 "\d"는 숫자를 의미합니까? (0) | 2022.11.19 |
MySQL에 코멘트를 추가하려면 어떻게 해야 하나요? (0) | 2022.11.19 |
fork()의 목적은 무엇입니까? (0) | 2022.11.19 |
ID 및 날짜를 기준으로 한 Row_number (0) | 2022.11.19 |