2010-01-03 13 views

risposta

48

Nelle versioni precedenti di Java, Marker Interfaces erano l'unico modo per dichiarare i metadati relativi a una classe. Ad esempio, l'interfaccia Markial serializzabile consente all'autore di una classe di dire che la classe si comporterà correttamente quando serializzata e deserializzata.

Nella moderna Java, le interfacce marker non hanno posto. Possono essere completamente sostituiti da Annotations, che consente una capacità di metadati molto flessibile. Se hai informazioni su una classe e tali informazioni non cambiano mai, le annotazioni sono un modo molto utile per rappresentarla.

+16

Mi piacciono molto le annotazioni ma in questo caso hanno lo svantaggio di essere un po 'più complicato da controllare (rispetto all'utilizzo di instanceof). Inoltre, non sono altrettanto integrati in javadoc (dove un modo rapido per vedere cosa implementa o meno l'interfaccia marker è semplicemente cercare e vedere l'elenco delle classi di implementazione). Quindi direi che hanno ancora un posto, ma non altrettanto importante. – Fredrik

+9

@ Chris così hai ragione o è Josh Bloch proprio qui? http://stackoverflow.com/a/5080547/632951 – Pacerier

+1

@Pacerier Direi che poiché le interfacce dei marker non definiscono alcun comportamento, sono essenzialmente prive di significato per la sicurezza del tipo.Solo perché una classe è marcata serializzabile non significa che possa essere serializzata correttamente, e la mancanza dell'interfaccia marcatore non implica che la serializzazione non funzionerebbe. Può solo significare che lo sviluppatore ha sbagliato a segnarlo! Se l'interfaccia avesse effettivamente dei metodi (e non fosse più un marker), allora avrebbe applicato un contratto di comportamento. È anche molto più lavoro includere metadati aggiuntivi con un'interfaccia marcatore, mentre con le annotazioni fa parte del punto. –

4

Indica che la classe (e di conseguenza tutti i campi che non sono transitori) sono candidati per la serializzazione. E se si sta costruendo un quadro affidamento sulla serializzazione, è possibile, naturalmente, scrivere un metodo così:

public void registerObject(Serializable obj); 

per limitare le classi siete disposti ad accettare.

Poiché un oggetto serializzato deve mantenere la compatibilità tra i sistemi, la serializzazione è una decisione di progettazione esplicita e quindi richiede l'uso dell'interfaccia marker per identificare tali candidati.

C'è anche un aspetto di sicurezza. Non si desidera rendere tutto serializzabile, altrimenti è possibile esporre accidentalmente (ad esempio) password o altri dati sensibili tramite la serializzazione.

6

Tali interfacce marcatore sono utili nel caso in cui un altro codice prenda decisioni a seconda che un oggetto implementa un'interfaccia marker.

Nel caso di Serializable, la riflessione verrà utilizzata per serializzare i campi degli oggetti.

Ora le annotazioni sono preferite in quanto non si propagano alle sottoclassi.

Vedere Marker interface pattern.

+2

Serializable, non ISerializable :) – Bozho

+1

sì ho messo su, sto sempre anteponendo i miei nomi di interfaccia con la "I" :) –

+3

@Gregory Heresy, questo è Java! E anche nel mondo .NET, questa convenzione (cattiva) COM dovrebbe essere dimenticata! –

2

Si chiamano marker interfacce. E come suggerisce il nome, sono contrassegnare che alcuni oggetti sono disponibili per determinati tipi di operazioni.

Serializable significa che l'oggetto è idoneo per la serializzazione java, ad esempio.

È stato discusso se non dovrebbero essere sostituiti da annotazioni, poiché le loro funzioni sono abbastanza simili.

2

Se si implementa un'interfaccia, allora instanceof sarà vero. Se l'interfaccia non ha nulla da implementare, puoi usarla per marcare una classe con meta-dati come le annotazioni per Java 1.5 e fino senza dover forzare l'implementatore a fare qualcosa di speciale.

1

Hai ragione nel ragionare sul fatto che un'interfaccia vuota non influisce sull'esecuzione "standard" del programma che si basa sull'ispezione/mutazione dei campi e sull'invio dei metodi.

Tuttavia, l'interfaccia marcatore è utile se utilizzata in combinazione con la riflessione: una libreria/metodo ispeziona (tramite riflessione) un oggetto e funziona in modo diverso se la sua classe implementa l'interfaccia marker. A partire da Java5 c'è pochissima necessità di interfacce marker - la stessa funzionalità di "marking" può essere ottenuta tramite annotazioni Java - che (ancora) la maggior parte del loro effetto sarà raggiunta tramite il codice basato su reflection.

75

Joshua Bloch: Effective Java 2 ° edizione, pag 179

Articolo 37: utilizzare le interfacce marcatori per definire i tipi

... si può sentire dire che segnalino annotazioni (Voce 35) rendono le interfacce marcatore obsolete. Questa affermazione è errata. Le interfacce marker hanno due vantaggi rispetto alle annotazioni dei marker. Innanzitutto, le interfacce marker definiscono un tipo implementato dalle istanze della classe contrassegnata; marcatore annotazioni no. L'esistenza di questo tipo permette di individuare gli errori in fase di compilazione che non si poteva cattura fino al runtime se è stato utilizzato un'annotazione marcatore ....

Personalmente penso che mi inchino a Joshua di Conoscenza superiore su questo argomento.

+2

Yup ... molto bello :) – agpt

+0

Il problema è che spesso contraddice l'articolo 19: utilizzare le interfacce solo per definire i tipi. "Serializable" non è un tipo, è una proprietà/comportamento. –

+3

In realtà, anche "Serializable" può essere visto come un tipo. Prendere in considerazione la seguente firma del metodo: serialize publicize (Serializable objectToSerialize); In questo caso, è chiaro al momento della compilazione che solo gli oggetti serializzabili possono essere passati a "serialize", questo non è possibile con le annotazioni. –

-1

Lo scopo principale è di dire al compilatore di trattare diversamente per l'oggetto della classe che ha implementato l'interfaccia marker.

+1

Questo è assolutamente sbagliato. Il compilatore Java o JVM non fa nulla di speciale per Serializable e altre interfacce marker, ma le classi di librerie java che lo consumano devono riconoscere gli oggetti Serializable e possono considerarlo e processare in modo diverso tali oggetti, ma non il compilatore o JVM. Questo è un malinteso comune sulle interfacce Marker. –

-1

Osservare attentamente l'interfaccia marker in Java, ad es. Serializable, Clonnable e Remote sembra che siano usati per indicare qualcosa al compilatore o alla JVM. Quindi, se JVM vede che una classe è serializzabile, ha fatto qualche operazione speciale su di essa, in modo simile se JVM vede una classe implementare Clonnable esegue alcune operazioni per supportare la clonazione. Lo stesso vale per l'interfaccia RMI e Remote. Quindi in breve l'interfaccia Marker indica, segnala o invia un comando a Compiler o JVM.

Per saperne di più: http://javarevisited.blogspot.com/2012/01/what-is-marker-interfaces-in-java-and.html#ixzz2v6fIh1rw

+1

Questo è assolutamente sbagliato. Il compilatore Java o JVM non fa nulla di speciale per Serializable e altre interfacce marker, ma le classi di librerie java che lo consumano devono riconoscere gli oggetti Serializable e possono considerarlo e processare in modo diverso tali oggetti, ma non il compilatore o JVM. Questo è un malinteso comune sulle interfacce Marker. –

Problemi correlati