Esistono parecchi linguaggi di programmazione, alcuni sono interpretati e altri sono compilati (sono due grandi famiglie).
Quelli interpretati sono linguaggi che hanno bisogno, appunto, di un interprete per poter essere eseguiti: praticamente l'interprete fa da tramite NON convertendo il codice in un linguaggio comprensibile alla CPU, ma interpretando il codice). Python, per farti un nome, è interpretato.
I compilati sono quei linguaggi che fanno appunto uso di un compilatore: questo traduce il codice sorgente del programmatore in un linguaggio di più basso livello; praticamente lo stesso che è direttamente comprensibile alla CPU, quindi non servono intermediari in questo caso.
Esiste un'altra tipologia tra quelli compilati, ovvero quelli semi-interpretati: Java è uno di questi. Nel caso di Java esiste un compilatore, ma invece di produrre un codice comprensibile direttamente alla CPU (che nel nostro caso spesso, quasi sempre, è x86_64 o x86), produce una forma intermedia chiamata bytecode. Un file .JAR (se apri la cartella di quel software e navighi nelle varie folder, troverai tanti .jar) è un archivio che contiene solitamente molteplici file ".class" (che sono i file che contengono questo bytecode).
Quando clicchi su un JAR viene lanciata la macchina virtuale di Java, che interpreta questo codice e lo traduce nel linguaggio comprensibile alla CPU; ora in realtà non è proprio così, è un pò diverso (java usa i JIT ormai, che in soldoni, traducono direttamente il ccodice senza "interpretarlo", ed è più rapido)... ma non voglio tediare con dettagli inutili.

Sti benedetti linguaggi che producono del codice nativo sono un sacco, come C, C++, Go, Rust... etc etc.
Specifico exe/dll nativi: ci sono exe non nativi, e sono quelli generati da file sorgenti scritti ad esempio in C#, che producono un codice chiamato MSIL (Microsoft intermediate language).