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.