|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
[java] interfaccia Cloneable
Non riesco a capire a cosa potrebbe servire l'interfaccia Cloneable!
![]() non ha nessun metodo, e inoltre sembra che tutte le classi la estendano!!! o mi sbaglio??!! ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
|
Come dicono le specifiche, se una classe non estende l'interfaccia "Cloneable", non è possibile invocare il metodo "clone()" della classe Object, che tutti gli oggetti naturalmente ereditano.
Il metodo "clone()" (ma dalla tua domanda penso che tu lo sappia già) serve per tutti i casi in cui si voglia ottenere una "copia di lavoro" di un'oggetto su cui operare senza alterare il contenuto dell'originale: altrimenti, ricordando che ciò che viene passato nelle chiamate ai metodi è un riferimento all'oggetto stesso (salvo il caso dei tipi elementari), qualsiasi azione che ne alteri lo stato risulterà "visibile" anche su tutti i dententori dei riferimenti all'oggetto medesimo, con conseguenze spesso indesiderabili. Il metodo "clone()" della classe Object inoltre è un metodo generico di copia degli oggetti, e in quanto tale non è adatto a tutte le tipologie di classi che si possono creare: è meglio, in caso di incertezza, fare l'override del metodo clone nella classe che implementa l'interfaccia Cloneable, in maniera che la copia sia "informata" della struttura dell'oggetto che sta copiando e pertanto la procedura sia al contempo corretta e completa.
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN |
![]() |
![]() |
![]() |
#3 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
clone su E
ok... ma se devo clonare un oggetto generico? ad esempio :
ho un dato definito così E elemento1 che viene inizializzato nel main, e devo fare un clone di elemento1 e metterlo in elemento2. Come si fa? il compilatore mi dice che clone è definito protected in Object (giustamente), ma allora come faccio ad usare clone() su elemento1 ? |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
|
Quote:
Oppure "E" è un tipo generico?
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN |
|
![]() |
![]() |
![]() |
#5 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
la seconda!... "E" è un tipo generico (i generics...)
Questo problema mi sta facendo impazzire! |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
|
Boh... non potresti semplicemente provare a clonare l'oggetto e lanciare la "CloneNotSupportedException" in caso che E non sia Cloneable?
Il fatto è che, o sei sicuro per le tue specifiche che ogni E è Cloneable oppure può darsi che qualche E non lo sia: in tal caso sarebbe corretto informare l'utilizzatore dell'errore. Sul come poi, vedi tu...
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN |
![]() |
![]() |
![]() |
#7 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
ho già provato a fare così, ma siccome E è generico il compilatore mi da errore dicendomi che E non può utilizzare la clone di Object perchè protected... (il programma non si eseguirà mai così!!)
inoltre se faccio un instanceof Clonable sull'oggetto di tipo E per vedere se implementa l'interfaccia, mi dà sempre una risposta positiva (in quanto l'interfaccia Cloneable non contiene nessun metodo), quindi mi eseguira la clone() anche se è un oggetto che non sovrascrive il metodo! |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Credo che l'unica soluzione sia usare la "reflection". Prendi la classe dell'oggetto "generico", cerchi il metodo "clone" e se c'è lo invochi.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
|
Quote:
Codice:
elemento2 = (E)((Cloneable)elemento1).clone(); ![]()
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Le classi che concretizzano cloneable non sono poi tantissime. Il fatto che non abbia metodi non significa che tutti quanti siano dei Cloneable. E' un marcatore puro, tipo EventListener.
Dichiara E sottotipo di Cloneable e poi usa la clonazione standard.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#11 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
finalmente ho risolto il problema!!
grazie a Andbin ho usato le reflection e tutto si è risolto... usare il cast a clonable provocava sempre un errore al compilatore in quanto Cloneable non ha alcun metodo (e quindi neanche clone()).. ![]() |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
|
Quote:
![]() [/Riflessione Pseudo-filosofica sul linguaggio]
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Io ho provato a fare così:
Codice:
import java.lang.reflect.*; import java.io.*; import java.util.*; public class Prova { public static void main (String[] args) { try { // Date e` clonabile Contenitore<Date> c = new Contenitore<Date> (new Date ()); Contenitore<Date> c2 = (Contenitore<Date>) c.clone (); } catch (Exception e) { System.out.println (e); } try { // File non e` clonabile Contenitore<File> c = new Contenitore<File> (new File ("prova")); Contenitore<File> c2 = (Contenitore<File>) c.clone (); } catch (Exception e) { System.out.println (e); } } } class Contenitore<T> implements Cloneable { private T var; public Contenitore (T var) { this.var = var; } public Object clone () throws CloneNotSupportedException { Contenitore<T> newobj = (Contenitore<T>) super.clone (); if (var != null) newobj.var = (T) cloneObj (var); return newobj; } private Object cloneObj (Object o) throws CloneNotSupportedException { try { Class<?> cl = o.getClass (); Method m = cl.getMethod ("clone", new Class[0]); return m.invoke (o, new Object[0]); } catch (NoSuchMethodException e) { throw new CloneNotSupportedException (); } catch (IllegalAccessException e) { throw new CloneNotSupportedException (); } catch (InvocationTargetException e) { throw new CloneNotSupportedException (); } } public T getVar () { return var; } public void setVar (T var) { this.var = var; } } ![]()
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#14 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
anche secondo me... Cloneable non è altro che una descrizione/proprietà di una classe con la quale si dice che dentro è sovrascritto il metodo clone (messo public anzichè di private). Per il resto l'interfaccia non ha niente dentro; mi viene da pensare che sia molto simile ad una classe astratta!
|
![]() |
![]() |
![]() |
#15 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
|
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Potreste usare:
public class Contenitore<T extends Cloneable> implements Cloneable {... Formalmente questo assicura che la clonazione di T non produca mai una CloneNotSupportedException (ammesso che chi ha scritto la classe T che implementa Cloneable rispetti lo standard della clonazione in Java). Per invocare un metodo pubblico senza argomenti: val.getClass().getMethod("clone").invoke(val); Continuo a preferire il costruttore di copie ![]()
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#17 | |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
Quote:
Grazie cmq di avermi detto come si invoca il metodo pubblico senza argomenti! ![]() |
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Preciso a scanso di equivoci ma è solo una formalità. L'invocazione riflessiva che ho incollato è, per via dei varargs, uguale a quella di andbin. Non ci sono due modi per invocare un metodo pubblico. Ce n'è uno solo
![]() Introducendo un limite nella dichiarazione del tipo generico ottieni un controllo di compatibilità in compilazione. C'è tutta la diatriba sulla tip(azione/izzazione) statica dietro e se andiamo in giro declamando "tanto il controllo lo fa in esecuzione" c'è il rischio che volino coltellate tra le scapole. Io parteggio per il versante dinamico ma occhi aperti che gli statici son agguerriti ![]()
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#19 |
Junior Member
Iscritto dal: Mar 2007
Messaggi: 22
|
meglio aggiungerlo allora... cosi' il codice mi diventa piu' robusto!!
![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 01:23.