Se il mio IDE è così intelligente, perché devo lanciare "clone ()"?

13

Il mio IDE ( NetBeans ) controlla il mio Collections mentre sto digitando il codice. Ma allora, perché devo lanciare l'oggetto restituito di Object.clone() ? Che va bene Nessun danno nessun fallo. Ma ancora, non capisco.

Il controllo del tipo, senza eseguire il casting, non è possibile restituire l'oggetto Object.clone() ? Il framework generics mi fa pensare che l'IDE possa controllare il tipo di riferimenti a oggetti sul lato destro del segno " = " senza eseguire il cast mentre Sto scrivendo? Non capisco.

addendum
Il mio caso di utilizzo era che avevo un campo Calendar privato, pubdate . Stavo per scrivere:

Calendar getPubdate() {
    return pubdate;
}

ma c'è il rischio che l'invoker possa modificare il mio pubdate , quindi ho restituito una copia:

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

Quindi mi sono chiesto perché avevo bisogno di lanciare pubdate.clone() . La firma del metodo ha il tipo giusto lì. NetBeans dovrebbe essere in grado di capirlo. E NetBeans sembrava fare qualcosa di simile per quanto riguarda Collections .

    
posta konishiki 15.03.2016 - 12:34
fonte

4 risposte

53

why do I have to cast the returned object of Object.clone()?

Perché restituisce Object .

The generics framework makes me think the IDE could check the type of object references on the right-side of the "=" mark without casting while I am typing? I don't get it.

Object.clone non è generico.

Se i generici esistevano quando è stato progettato clone , probabilmente sarebbe stato simile a questo (usando il polimorfismo F-Bounded):

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

Se Java ha una funzione MyType, potrebbe essere simile a questa:

interface Cloneable {
  this clone();
}

Ma Generics non esisteva quando Object.clone è stato progettato, e Java non ha MyTypes, quindi la versione non sicura del tipo di Object.clone è ciò con cui dobbiamo lavorare.

    
risposta data 15.03.2016 - 12:44
fonte
26

Questa non è una caratteristica di nessun IDE, ma della definizione della lingua.

Un IDE ti aiuta a usare un linguaggio di programmazione in modo più efficiente, non cambia la semantica di quel linguaggio. Ciò significa che un helper dell'editor potrebbe inserire automaticamente un cast quando è ovvio quale vuoi, ma non può semplicemente infrangere le regole del linguaggio e fingere che il codice che non è compilato sia valido.

Modifica È vero che un IDE può raggruppare il proprio compilatore e in effetti molti lo fanno esattamente, ad es. per una migliore segnalazione degli errori con più informazioni interne nella struttura di analisi parziale. Tuttavia, sarebbe una pessima idea lasciare che questo compilatore interno implementasse una semantica linguistica diversa dall'SDK ufficiale, dal momento che ciò significherebbe che il codice che funziona in sviluppo può misteriosamente iniziare a fallire quando installato in produzione - producendo problemi che sono per definizione non-debuggabili!

    
risposta data 15.03.2016 - 12:47
fonte
3

È dovuto alla firma del tipo del metodo Object.clone. La firma del tipo afferma che il metodo restituirà un oggetto di tipo Object.

protected Object clone() throws CloneNotSupportedException

Le raccolte useranno i cosiddetti tipi generici per sostituire automaticamente il tipo di casting.

Quindi se hai questo codice:

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

il compilatore aggiungerà i cast per te dietro le quinte, quindi il codice sarebbe in realtà:

List ints = Arrays.asList(1,2,3);
int x = (Integer)ints.get(0);
    
risposta data 15.03.2016 - 12:47
fonte
0

Per completezza, dal momento che Java 5, tipi di ritorno covarianti sono consentiti . Quindi puoi scrivere quanto segue:

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

Con questo, il seguente codice è legale:

MyObject original = new MyObject();
MyObject clone = original.clone();
    
risposta data 16.03.2016 - 16:17
fonte

Leggi altre domande sui tag