2016-02-19 14 views
5

La mia domanda iniziale era un duplicato esatto di this one; cioè, perché questa interfaccia ha un criterio di conservazione del runtime.In che modo @FunctionalInterface influenza il comportamento di runtime della JVM?

Ma la risposta accettata non mi soddisfa del tutto, per due motivi:

  • il fatto che questa interfaccia è @Documented ha (credo) nulla a che fare con esso (anche se il motivo per cui @Documented ha una ritenzione di runtime la politica è un mistero anche per me);
  • anche se molte interfacce funzionali "sarebbero" esistevano in Java prima di Java 8 (ecc.), Ciò non impedisce che vengano utilizzate come "sostituti" (ad esempio, è possibile perfavore usa uno DirectoryStream.Filter come sostituto a Predicate se tutto ciò che fai è filtrare su Path, per esempio).

Tuttavia, ha questa ritenzione. Ciò significa che deve influenzare il comportamento della JVM in qualche modo. Come?

+1

Questa è una conclusione molto strana che avere il criterio di conservazione 'RUNTIME' implica che abbia un'influenza sul comportamento della JVM. Dato che sai già che puoi implementare interfacce funzionali con espressioni lambda, anche quando non hanno quell'annotazione (suppongo che tu lo sappia), quale tipo di cambiamento nel comportamento di JVM dovrebbe avere qualcosa di completamente opzionale? – Holger

+0

@Holger è esattamente quello che mi chiedevo, da qui la domanda. Ma alla fine sembra che non faccia alcuna differenza ... – fge

risposta

4

Ho trovato lo thread nella mailing list core-libs-dev che discute la conservazione dell'annotazione @FunctionalInterface. Il punto principale qui citato è di consentire agli strumenti di terze parti di utilizzare queste informazioni per l'analisi/convalida del codice e di consentire ai linguaggi JVM non Java di mappare correttamente i loro lambda alle interfacce funzionali. Alcuni estratti:

Joe Darcy (committer originale del @FunctionalInterface):

Abbiamo volutamente fatto questa annotazione soffre di ritenzione runtime per permettergli di essere interrogato per vari strumenti in fase di runtime, ecc

Brian Goetz

C'è un vantaggio per le lingue altro rispetto a Java, che può utilizzare questo come mezzo per determinare se l'interfaccia è adatta per passare al macchinario di conversione SAM. Il supporto JDK per la conversione lambda è disponibile anche in altre lingue.

Quindi sembra che non sia usato da JVM stesso, è solo un'ulteriore possibilità per strumenti di terze parti.Rendere visibile il runtime delle annotazioni non è un grosso costo, quindi sembra che non ci fossero motivi validi per non fare .

+1

In realtà, rendere visibile un runtime di annotazione * riduce * i costi. La rappresentazione del codice byte è identica, solo il nome dell'attributo cambia da 'RuntimeInvisibleAnnotations' a' RuntimeVisibleAnnotations', quindi stai andando a salvare almeno due byte per file di classe. Dato che potresti avere altre annotazioni sul runtime visibili mentre le annotazioni invisibili sono molto rari, il salvataggio potrebbe essere ancora più elevato in quanto potrebbe evitare di avere entrambi i nomi degli attributi presenti in un file di classe. – Holger

+1

@Holger, mentre può ridurre un po 'la dimensione del file di classe, aumenta il costo di runtime quando le annotazioni visibili a runtime diventano oggetti java quando si richiede 'Class.getAnnotations()'. Sembra che, se richiesto, le informazioni su '@ FunctionalInterface 'rimarranno in memoria fino a quando la classe non viene scaricata, anche se in realtà hai cercato altre annotazioni. Tuttavia, questo non è un costo molto elevato dato che solo una piccola parte delle classi caricate è annotata con '@ FunctionalInterface'. –

1

L'unico requisito per le annotazioni con tempo di esecuzione dei criteri di conservazione è

annotazioni devono essere registrati nel file di classe dal compilatore e trattenuto dalla VM in fase di esecuzione, in modo che possano essere letti in modo riflessivo. (https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html#RUNTIME)

Ora questo ha delle conseguenze sul comportamento di esecuzione, dal momento che il caricatore di classe deve caricare questi annoations e la VM deve tenere queste annotazioni nella memoria per l'accesso riflettente (ad esempio librerie di terze parti).

Non vi è tuttavia alcun obbligo per la VM di agire su tali annotazioni.

Problemi correlati