Per quali ragioni Java e C # inizializzano i dati statici su richiesta?

3

Sto leggendo "The Go Programming Language" in questo momento e ho letto il capitolo di inizializzazione del pacchetto che dice (o che ho letto male) che Go usa con entusiasmo l'inizializzazione.

Quindi nel tempo abbiamo visto dire C ++ inizializzazione avidamente, poi Java con inizializzazione su richiesta, C # anche su richiesta, e Torna con un'inizializzazione ansiosa (quelle lingue non sono strettamente correlate, sto parlando di tempo).

E sono curioso dei motivi (nella prospettiva storica ) del perché il modello on-demand è stato scelto per Java e C #.

    
posta greenoldman 24.01.2016 - 16:01
fonte

2 risposte

7

C ++ e Go sono progettati per la compilazione del codice macchina nativo. Entrambi hanno una fase durante la costruzione in cui i moduli separati sono collegati insieme per produrre un singolo modulo combinato. Una volta che questo è stato fatto, è disponibile un elenco completo di tutti gli oggetti disponibili. Pertanto, il modo più semplice per inizializzare qualsiasi oggetto che richiede l'inizializzazione è scansionare quell'elenco, controllare il codice init e chiamarlo (potrebbe esserci un po 'più di sottigliezza rispetto a questo, ma come livello concettuale ampio è abbastanza vicino a come funziona ai fini di questa discussione).

Java e C # sono stati entrambi progettati per essere eseguiti in un ambiente di macchina virtuale. Java specificamente è stato progettato per eseguire caricamento su richiesta del codice. Il collegamento viene differito fino al runtime per consentire, ad esempio, ai moduli di risiedere su un server remoto dove possono essere aggiornati senza modificare il programma rimanente (questo è importante per lo scopo progettato originariamente di Java, che era per scrivere applicazioni per sistemi smart tv) . Inoltre, le classi possono essere aggiunte al sistema in fase di esecuzione (utilizzando Class.forName). Ciò significa che è impossibile per un'applicazione Java determinare un elenco completo di tutte le classi che può essere utilizzato in fase di compilazione o anche quando l'applicazione inizia a funzionare. Pertanto è impossibile per Java eseguire l'inizializzazione all'avvio dell'applicazione.

C #, AFAIK, aveva un obiettivo di progettazione che doveva essere in grado di essere utilizzato per qualsiasi tipo di applicazione in cui Java potesse essere già utilizzato. Era quindi necessario seguire la guida di Java nell'utilizzo del caricamento su richiesta, anche se ha un passaggio di collegamento separato, perché non farlo renderebbe difficile supportare applicazioni caricate in rete.

    
risposta data 24.01.2016 - 18:37
fonte
2

Le mie idee sul perché l'inizializzazione pigra potrebbe essere preferibile in .NET:

  1. Eager init può essere abbastanza difficile da eseguire il debug
    Non lo so, ma prima, quando ho avuto problemi con l'init statico in C ++, è stato un incubo e in alcuni casi ho preferito non usare static .
    Le dipendenze statiche di init possono essere un mal di testa anche in C #, per fortuna sono molto più facili da eseguire il debug e ci sono anche possibilità di test limitate. Vedi questo post di Jon Skeet per ulteriori informazioni.
  2. Come evitare init non necessario A differenza delle costanti C ++, le costanti .NET non sono molto potenti e quindi static vede un utilizzo molto ampio. Con una grande quantità di memoria inizializzata staticamente, potrebbe essere più saggio inizializzarla su richiesta piuttosto che prolungare ulteriormente l'avvio del programma che può già essere un problema con un linguaggio compilato da JIT.
    Questo è simile all'utilizzo esclusivo di. Dll da parte di .NET e al loro caricamento dinamico durante l'esecuzione del programma.
risposta data 24.01.2016 - 16:42
fonte

Leggi altre domande sui tag