modificadores acceso java oop clone access-modifiers

acceso - protected java



Accediendo a clone() desde java.lang.Object (4)

¿Qué quiere decir con "no poder acceder"? ¿Quiere decir que no compilará o quiere decir que arroja la CloneNotSupportedException?

Object.clone() lanzará CloneNotSupportedException si su clase no implementa la interfaz Cloneable.

Aquí hay algo que no puedo entender.

En java.lang.Object el clone() se define con protected modificador protected . Por definición, se puede acceder por nombre dentro de su propia definición de clase, por nombre dentro de cualquier clase derivada de él, y por nombre en la definición de cualquier clase en el mismo paquete.

Aquí la clase Sample está en otro paquete, y obviamente no puede acceder a clone() desde la clase Object . Pero como Sample deriva implícitamente de Object , ¿por qué no puede acceder? La definición no dice que TIENE que satisfacer ambas condiciones (dentro del mismo paquete Y también para ser una subclase).

public class Sample { public Object foo() throws CloneNotSupportedException { ... return someObject.clone(); } }


El tipo de clase de someObject es importante aquí. Object someObject no puede anular el método clone() de la clase Object , por lo que es invisible para la clase Sample .


En su caso, el método clone() no es visible porque no lo está llamando desde una subclase. Sample deriva de Object , por lo que puede acceder a su propio método clone() , pero no a otros objetos.

Object clone() se diseñó con varios errores. Por lo tanto, no es una buena práctica usarlo; es muy difícil hacerlo bien:

  • la suposición es que no todos los objetos son clonables por defecto
  • Si invalida clone() haciéndolo público, aún fallará, porque cada clase tiene que implementar Cloneable
  • Cloneable embargo, el Cloneable no define ningún método, por lo que los usuarios de los objetos no pueden referirse a él como Cloneable y esperan un método de clonación.
  • cada clase en una jerarquía debe llamar a super.clone() para que el mecanismo de clonación predeterminado funcione

Verifique esta pregunta por alternativas.


Funciona para mí: http://ideone.com/eST8Y

import java.util.*; import java.lang.*; class Main { public Object foo() throws CloneNotSupportedException { return this.clone(); } public static void main (String[] args) throws java.lang.Exception { new Main().foo(); } }

Esto compila sin error. Aún arroja una CloneNotSupportedException tiempo de ejecución porque Main no implementa Cloneable .

Una clase implementa la interfaz Cloneable para indicar al método Object.clone() que es legal que ese método realice una copia de campo de campo para las instancias de esa clase.

Invocar el método de clonación de Object en una instancia que no implementa la interfaz Cloneable da como resultado la excepción de que se lanzó CloneNotSupportedException .

La respuesta de @ Bozho es realmente la respuesta correcta aquí, sin embargo. Simplemente no use Object.clone() .

Ver Java efectivo , elemento 10: Anular el clone juiciosamente (Ítem 11 en ediciones posteriores).