Il J# (pronunciato "J sharp") è un linguaggio di programmazione nato espressamente per consentire ai programmatori Java (della Sun Microsystems) ed ai programmatori Visual J++ (della Microsoft) di utilizzare le proprie conoscenze esistenti nella migrazione verso i linguaggi della piattaforma .NET. Come il J++, anche il J# supporta solo una parte delle funzionalità di Java.
Se si vuole eseguire codice Java scritto per piattaforma Java su piattaforma .NET si può ricorrere a IKVM. Infatti, mentre J# implementa una sintassi Java compatibile col.NET framework, IKVM rende il framework Java totalmente eseguibile in ambiente.NET framework.
Nel gennaio 2007, Microsoft ha annunciato che produrrà una versione aggiornata di J# 2.0, tra cui una versione ridistribuibile per 64 bit, chiamata J# 2.0 Second Edition al fine soddisfare la domanda dei clienti per il supporto Run-time, la quale venne introdotta nel maggio seguente.
Microsoft ha deciso di non procedere oltre nello sviluppo del linguaggio, nonostante ciò continuerà a supportare J# e la tecnologia JLCA (Java Language Conversion Assistant) fino al 2015.
Il linguaggio è ormai fuori dal supporto mainstream, gli ultimi ad avere il supporto sono stati i residenti negli Stati Uniti, i quali hanno ricevuto il supporto extra fino al 2017.
Principali differenze fra J# e Java
J# e Java usano sintassi molto simili, ma le API utilizzate dai due linguaggi sono diverse. Un esempio è la classe FileOutputStream che, invece di accettare come parametro un riferimento ad un oggetto File come in Java, in J# accetta un oggetto String contenente il percorso completo del file.
J# non riesce però a compilare un codice sorgente Java in bytecode (file.class), inoltre non supporta lo sviluppo di applet e la possibilità di ospitarle in un browser web, nonostante disponga del supporto Microsoft J# Browser Controls per l'hosting di ActiveX.
InfoWorld ha detto: "L'interfaccia di J# è solida, ma non così perfetta come quella di C#: in particolare J# non può definire nuovi attributi.NET, gli eventi, i tipi di valore, o delegati J# può fare uso di questi costrutti se sono definiti in un assembly scritto in un altro linguaggio, ma la sua incapacità di definirne di nuovi limiti la portata e l'interoperabilità di J# rispetto ad altri linguaggi .NET".