2009-08-18 21 views

risposta

5

Perché a volte, ha davvero senso se alcune proprietà di un tipo possono essere utilizzate come un tipo stesso - mi viene in mente Serializable. Se faccio un metodo come questo:

public void save(Object data){ ... } 

... non so davvero come saranno salvati che data. Serializzazione VM? Serializzazione delle proprietà dei bean? Qualche schema homebrewed? Mentre se si scrive così:

public void save(Serializable data){ ... } 

... è del tutto evidente (anche se solo il progettista di ObjectOutputStream aveva usato questa possibilità!). A volte ha senso utilizzare le annotazioni quando si desidera aggiungere metadati ai tipi, ma in questo caso, direi un'interfaccia di codifica.

1

E 'stato usato per menzionare alcune proprietà di una classe (come mostra Serializable, che alla classe è permesso di serializzare). Ora le annotazioni potrebbero fare questo lavoro.

+0

No, le annotazioni non sono un sostituto per le interfacce marcatori. – skaffman

+1

@skaffman: è qualcosa di diverso dal fatto che è più difficile controllare un'annotazione piuttosto che un'interfaccia che ti fa dire che "le annotazioni non sono una sostituzione delle interfacce marcatore"? –

+0

Si può annotare un codice diverso dalle classi. Si possono anche usare annotazioni con argomenti. Ad esempio, prendi l'annotazione di validazione JSR 305 '@ ScriptAssert'. –

6

Un'interfaccia di codifica ha in genere un po 'di magia ad essa associata: o direttamente incorporata nella VM, o usando la riflessione. Poiché la magia potrebbe applicarsi tecnicamente a qualsiasi classe, usi la codifica per indicare che hai pensato bene alla magia e se si applica alla tua classe.

+0

Questa è l'unica riproduzione dell'interfaccia marcatore di ruolo. – adatapost

+0

E '? Mi sembra che estendere un'interfaccia di tagging possa fornire un controllo dei tipi in fase di compilazione per metodi che accettano solo oggetti il ​​cui tipo è un'estensione dell'interfaccia di codifica. Guarda EventListenerList.add, ad esempio. –

6

La domanda di interfacce marcatori vs annotazioni è discusso in "Effective Java" di Bloch, e parte di quella sezione è disponibile sul Google books here

+0

+1 - Bloch, come al solito, riassume bene e risponde al mio commento/domanda sulla risposta di @Mementh. –

0

In aggiunta alle altre interfacce risposte marcatori possono anche essere utilizzati per specificare ulteriori proprietà di una classe che non è ereditata da qualche altra interfaccia già implementata. Un esempio di questo sarebbe l'interfaccia RandomAccess. Denota una collezione a cui è possibile accedere in modo casuale senza perdita di prestazioni e non è necessario accedervi tramite un iteratore per ottenere tali prestazioni.

0

Puoi taggare la tua classe con un'interfaccia di codifica per dire al tuo collega sviluppatore e al consumatore della tua classe che supporti esplicitamente tale funzionalità. Pensa a Serializable; qualcuno che ha bisogno di mantenere una sessione e usa la serializzazione per farlo può tranquillamente utilizzare un oggetto della classe.

Può essere ulteriormente utilizzato in riflessione; al giorno d'oggi è comune usare annotazioni per fare ciò, ma nei vecchi tempi è possibile ispezionare una classe, verificare se implementa una determinata interfaccia (come DAO) e in tal caso, elaborare ulteriormente l'oggetto (sto pensando all'annotazione Entità qui).

0

interfacce di codifica sono interfacce senza metodi astratti all'interno, sono utilizzati per aggiungere un tipo di dati per la classe che li implementa ed essere un'interfaccia principale di altre interfacce (in particolare con l'ereditarietà multipla nelle interfacce)

public interface name {} 
public interface john1 {} 
public interface john2 {} 
public interface Demo extends john1 , john2 , name {} 

** quando JVM vede l'interfaccia del nome, scoprirà che la Demo eserciterà un cenario specifico.

0

Vorrei anche aggiungere è possibile utilizzare le interfacce di tagging per limitare la proprietà di un'istanza:

interface IFlumThing; 
interface IFlooThing; 

class BaseThing {...} 

class FlumThing extends BaseThing implements IFlumThing {}; 
class FlooThing extends BaseThing implements IFlooThing {}; 

class Flum { 
    addThing(IFlumThing thing){...}; 
} 

class Floo { 
    addThing(IFlooThing thing){...}; 
}