Si mi IDE es tan inteligente, ¿por qué necesito lanzar "clone ()"?

13
El tipo

Mi IDE ( NetBeans ) comprueba mi Collections mientras estoy escribiendo el código. Pero entonces, ¿por qué tengo que lanzar el objeto devuelto de Object.clone() ? Lo cual está bien. No hay daño no falta. Pero aún así, no entiendo.

¿No es posible verificar el tipo, sin conversión, el objeto devuelto de Object.clone() ? El marco generics me hace pensar que el IDE podría verificar el tipo de referencias de objetos en el lado derecho de la marca "=" sin lanzar ¿Estoy escribiendo? No lo entiendo.

addendum
Mi caso de uso fue simplemente que tenía un campo privado Calendar , pubdate . Iba a escribir:

Calendar getPubdate() {
    return pubdate;
}

pero existe el riesgo de que el invocador pueda modificar mi pubdate , por lo que devolví una copia:

Calendar getPubdate() {
    return (Calendar) pubdate.clone();
}

Entonces, me pregunté por qué necesitaba lanzar pubdate.clone() . La firma del método tiene el tipo justo allí. NetBeans debería poder resolverlo. Y NetBeans parecía estar haciendo algo similar con respecto a Collections .

    
pregunta konishiki 15.03.2016 - 12:34

4 respuestas

53
  

¿Por qué tengo que convertir el objeto devuelto de Object.clone() ?

Porque devuelve Object .

  

El marco genéricos me hace pensar que el IDE podría verificar el tipo de referencias de objetos en el lado derecho de la marca "=" ¿Sin fundir mientras estoy escribiendo? No lo entiendo.

Object.clone no es genérico.

Si los genéricos hubieran existido cuando se diseñó clone , probablemente se vería así (utilizando el polimorfismo de límite F):

interface Cloneable<T extends Cloneable<T>> {
  T clone();
}

Si Java tuviera una función MyType, quizás se vería así:

interface Cloneable {
  this clone();
}

Pero los genéricos no existían cuando se diseñó Object.clone y Java no tiene MyTypes, por lo que tenemos que trabajar con la versión de tipo no seguro de Object.clone .

    
respondido por el Jörg W Mittag 15.03.2016 - 12:44
26

Esta no es una característica de ningún IDE, sino de la definición de idioma.

Un IDE te ayuda a usar un lenguaje de programación de manera más eficiente, no cambia la semántica de ese lenguaje. Eso significa que un editor auxiliar puede insertar automáticamente una conversión cuando es obvio cuál quieres, pero no puede simplemente romper las reglas del idioma y pretender que el código que no se compila es válido.

Editar Es cierto que un IDE puede agrupar su propio compilador, y de hecho muchos lo hacen exactamente, por ejemplo. para un mejor informe de errores con más información interna en el árbol de análisis parcial. Sin embargo, sería una idea muy mala permitir que este compilador interno implemente una semántica de lenguaje diferente a la SDK oficial, ya que eso significaría que el código que funciona en el desarrollo puede comenzar a fallar misteriosamente cuando se instala en producción. Problemas que, por definición, no se pueden depurar!

    
respondido por el Kilian Foth 15.03.2016 - 12:47
3

Se debe a la firma de tipo del método Object.clone. La firma de tipo indica que el método devolverá un objeto de tipo Object.

protected Object clone() throws CloneNotSupportedException

Las colecciones utilizarán los llamados tipos genéricos para sustituir el tipo de conversión automáticamente.

Así que si tienes este código:

List<Integer> ints = Arrays.asList(1,2,3);
int x = ints.get(0);'

el compilador agregará las conversiones para usted entre bastidores, por lo que el código sería:

List ints = Arrays.asList(1,2,3);
int x = (Integer)ints.get(0);
    
respondido por el Miro 15.03.2016 - 12:47
0

Para completar, ya que Java 5, se permiten tipos de devolución covariantes . Para que puedas escribir lo siguiente:

public MyObject implements Cloneable {
  @Override
  public MyObject clone() {
    try {
      return (MyObject)super.clone();
    } catch (CloneNotSupportedException e) {
      throw new AssertionError();
    }
  }
}

Con esto, el siguiente código es legal:

MyObject original = new MyObject();
MyObject clone = original.clone();
    
respondido por el Olivier Grégoire 16.03.2016 - 16:17

Lea otras preguntas en las etiquetas