developer tip

clone () 메서드가 java.lang.Object에서 보호되는 이유는 무엇입니까?

copycodes 2020. 8. 13. 23:34
반응형

clone () 메서드가 java.lang.Object에서 보호되는 이유는 무엇입니까?


clone()에서 보호 되는 것으로 정의 된 구체적인 이유는 무엇입니까 java.lang.Object?


클론이 보호된다는 사실 cloneCloneable인터페이스 에서 메서드가 선언되지 않았기 때문에 매우 모호 합니다 .

다음과 같이 말할 수 없기 때문에 데이터 사본을 가져 오는 데 방법이 매우 쓸모 없게 만듭니다 .

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 복제 할 수없는 개체에서 호출해서는 안되므로 공개되지 않습니다.
  • #cloneObject올바른 클래스의 얕은 복사본을 얻으려면 Cloneable을 구현 하는 하위 클래스 ob에 의해 호출되어야합니다.

하위 클래스에서 호출 할 수 있지만 다른 클래스에서는 호출 할 수없는 메서드의 올바른 범위는 무엇입니까?

그것은이다 protected.

Cloneable물론 구현 하는 클래스 는이 메서드를 공개하므로 다른 클래스에서 호출 할 수 있습니다.


Clone () 메서드는 내부적으로 'instance of Cloneable 여부'를 확인합니다. 이것은 Java 팀이 clone () method.clone () 메서드의 부적절한 사용을 제한 할 것이라고 생각할 수있는 방법입니다. 즉, 하위 클래스에 의해서만 액세스됩니다. object는 모든 하위 클래스의 부모 클래스이므로 위의 'instance of Cloneable'확인이 없으면 모든 클래스에서 실제로 Clone () 메서드를 사용할 수 있습니다. 이것이 Java 팀이 clone () 메서드 'Cloneable의 인스턴스입니까'를 확인하여 clone ()의 부적절한 사용을 제한하려고 생각한 이유입니다.

따라서 cloneable을 구현하는 클래스는 Object 클래스의 clone () 메서드를 사용할 수 있습니다.

Also since it made protected, it is available to only those sub classes that implements cloneable interface. If we want to make it public, this method has to be overridden by the sub class with their own implementation of it.


Yes, same problem that I met. But I solve it by implementing this code

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;
    }
}

Just as the before someone said.


Well, also the sun developers are only human, and they did indeed make huge mistake to implement the clone method as protected, the same mistake as they implemented a non-functioning clone method in ArrayList! So, in general, there exist a much deeper misunderstanding of even experienced Java programmers about the clone method.

However, I've recently found a fast and easy solution to copy any object with all its content, no matter how it is built and what it contains, see my answer here: Bug in using Object.clone()


Again, Java JDK framework shows brilliant thinking:

Cloneable interface does not contain a "public T clone();" method because it acts more like an attribute (eg. Serializable) which allows an instance it to be cloned.

There is nothing wrong with this design because:

  1. Object.clone() will not do what you want with your custom-defined class.

  2. If you have Myclass implements Cloneable => you overwrite clone() with "public MyClass clone()"

  3. If you have MyInterface extends Cloneable and some MyClasses implementing MyInterface: simply define "public MyInterface clone();" in the interface and every method using MyInterface objects will be able to clone them, no matter their MyClass-class.

참고URL : https://stackoverflow.com/questions/1138769/why-is-the-clone-method-protected-in-java-lang-object

반응형