clone()
에서 보호 되는 것으로 정의 된 구체적인 이유는 무엇입니까 java.lang.Object
?
답변
클론이 보호된다는 사실 clone
은 Cloneable
인터페이스 에서 메서드가 선언되지 않았기 때문에 매우 모호 합니다 .
다음과 같이 말할 수 없기 때문에 데이터 사본을 가져 오는 데 방법이 매우 쓸모 없게 만듭니다 .
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
의 디자인 Cloneable
은 이제 대체로 실수로 간주 된다고 생각합니다 (아래 인용). 나는 일반적으로 인터페이스의 구현을 할 수 있기를 원 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 인용 :
“Cloneable 인터페이스는 객체가 복제를 허용한다고 광고하는 믹스 인 인터페이스로 의도되었습니다. 불행히도이 목적을 달성하지 못합니다 … 이것은 에뮬레이션 할 인터페이스가 아니라 매우 비정상적인 인터페이스 사용입니다. … 인터페이스를 구현하여 클래스에 영향을 미치려면 인터페이스와 모든 수퍼 클래스가 상당히 복잡하고 시행 할 수 없으며 대부분 문서화되지 않은 프로토콜을 따라야 합니다. “
답변
Clonable 인터페이스는 클래스가 복제를 지원할 수 있음을 나타내는 마커 일뿐입니다. 이 메서드는 객체에서 호출하지 않아야하기 때문에 보호되며 공용으로 재정의 할 수 있습니다 (그리고 그래야합니다).
Sun에서 :
Object 클래스에서 clone () 메서드는 보호 된 것으로 선언됩니다. Cloneable을 구현하기 만하면 동일한 패키지의 서브 클래스와 멤버 만 객체에서 clone ()을 호출 할 수 있습니다. 모든 패키지의 클래스가 clone () 메서드에 액세스 할 수 있도록하려면 아래 에서처럼이를 재정의하고 public으로 선언해야합니다. (메소드를 재정의 할 때 덜 비공개로 만들 수 있지만 더 비공개로 만들 수는 없습니다. 여기서 Object의 보호 된 clone () 메서드는 공용 메서드로 재정의됩니다.)
답변
clone
현재 클래스에 한정되도록 재정의해야하는 것이기 때문에 보호됩니다. clone
모든 객체를 복제 하는 공용 메서드 를 생성하는 것이 가능할 수 있지만 이는이 를 필요로하는 클래스를 위해 특별히 작성된 메서드만큼 좋지 않을 것입니다.
답변
Clone 메서드는 어떤 개체에서도 직접 사용할 수 없으므로 하위 클래스에 의해 재정의되도록되어 있습니다.
물론 공개 될 수 있고 복제가 불가능할 때 적절한 예외를 던질 수 있지만 오해의 소지가 있다고 생각합니다.
지금 복제가 구현되는 방식은 복제를 사용하려는 이유와 개체를 복제하는 방법에 대해 생각하게합니다.
답변
기본 구현이 모든 필드 (개인용 포함)의 얕은 멤버 별 복사를 수행하고 constructor를 우회 하기 때문에 보호됩니다 . 이것은 객체가 처음에 처리하도록 설계된 것이 아닙니다 (예를 들어, 공유 목록에서 생성 된 객체 인스턴스를 추적하거나 이와 유사한 것).
같은 이유로 기본 구현은 clone()
호출 된 객체가 Cloneable
. 광범위한 결과를 초래할 수있는 잠재적으로 안전하지 않은 작업이므로 클래스 작성자는 명시 적으로 옵트 인해야합니다.
답변
복제 가능의 javadoc에서.
* 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을 호출 할 수 있지만 원하는 결과 나 예외가 아닌 대부분의 시간을 제공합니다. 그러나 복제 가능을 구현하는 경우에만 권장됩니다.
답변
IMHO는 다음과 같이 간단합니다.
#clone
복제 할 수없는 개체에서 호출해서는 안되므로 공개되지 않습니다.#clone
Object
올바른 클래스의 얕은 복사본을 얻으려면 Cloneable을 구현 하는 하위 클래스 ob에 의해 호출되어야합니다.
하위 클래스에서 호출 할 수 있지만 다른 클래스에서는 호출 할 수없는 메서드의 올바른 범위는 무엇입니까?
그것은이다 protected
.
Cloneable
물론 구현 하는 클래스 는이 메서드를 공개하므로 다른 클래스에서 호출 할 수 있습니다.