C# et Java sont de proches parents. Tous deux sont des langages orientés objet, à typage statique et à ramasse-miettes, avec une syntaxe de style C ; tous deux sont compilés en bytecode pour une machine virtuelle et servent à de grands systèmes backend. C# est sorti en 2002, en partie comme la réponse de Microsoft à Java, et en deux décennies les deux langages se sont emprunté des fonctionnalités (lambdas, génériques, records, pattern matching). Un développeur qui connaît l'un peut lire l'autre presque immédiatement.
Les différences qui comptent au quotidien sont plus petites et plus précises. Cette page les passe en revue avec du code : des extraits C# que vous pouvez exécuter, et du Java dans des blocs statiques pour comparer.
En un coup d'œil
| C# | Java | |
|---|---|---|
| Créé par | Microsoft (2002) | Sun Microsystems (1995), aujourd'hui Oracle |
| Runtime | CLR (.NET), compile l'IL en code natif | JVM, compile le bytecode en code natif |
| Plateformes | Windows, Linux, macOS | Windows, Linux, macOS |
| Propriétés | Intégrées : public int Age { get; set; } | Méthodes getter et setter |
| Types valeur définis par l'utilisateur | struct | Pas encore (Project Valhalla) |
| Génériques | Réifiés : les types existent à l'exécution | Effacés : les types disparaissent après compilation |
| Interroger des collections | LINQ | API Streams |
| Asynchrone | async / await | Threads virtuels (Java 21), CompletableFuture |
| Exceptions vérifiées | Non | Oui |
| Surcharge d'opérateurs | Oui | Non |
| Sûreté vis-à-vis de null | Types référence nullables (C# 8) | Optional<T>, annotations |
| Usages principaux | Jeux Unity, ASP.NET Core, bureau Windows, Azure | Backends d'entreprise, Android, big data |
Syntaxe : presque identique
Les classes, méthodes, if, for, while, switch, try/catch se lisent presque de la même façon. Les différences visibles tiennent aux conventions de nommage et à quelques mots-clés : les méthodes C# sont en PascalCase (ToUpper, WriteLine), les méthodes Java en camelCase (toUpperCase, println) ; C# écrit string et bool, Java String et boolean ; l'héritage s'écrit class Dog : Animal en C# et class Dog extends Animal en Java.
// Java
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Ana");
names.add("Ben");
for (String n : names) {
System.out.println(n.toUpperCase());
}
}
}
Sortie :
ANA
BEN
C# compare aussi les chaînes par valeur avec ==, ce qui élimine l'un des bugs de débutant classiques de Java : en Java, == sur deux objets String compare des références, donc deux chaînes égales construites à l'exécution (lues depuis une saisie, concaténées) peuvent être jugées différentes.
Des propriétés au lieu des getters et setters
Les classes Java exposent leur état via des méthodes getName() et setName(), souvent générées par un IDE ou Lombok. C# a des propriétés : des membres qui se lisent comme des champs mais exécutent du code.
// Java
public class Product {
private double price;
public double getPrice() { return price; }
public void setPrice(double price) {
if (price < 0) throw new IllegalArgumentException("negative");
this.price = price;
}
}
Sortie :
Mug: 9.50
L'initialiseur d'objet new Product { Name = ..., Price = ... } définit les propriétés juste après la construction. Les records Java (Java 16) couvrent le cas des données immuables ; C# a aussi des records (C# 9), plus les propriétés pour tout le reste.
Les types valeur : les structs
En Java, chaque type défini par l'utilisateur est un type référence stocké sur le tas ; seuls les huit types primitifs (int, double, ...) sont des valeurs. C# permet de définir vos propres types valeur avec struct. Une struct est copiée à l'affectation et peut être stockée directement dans des tableaux et d'autres objets, sans allocation séparée sur le tas.
Sortie :
a = (1, 2)
b = (99, 2)
1000
C'est important dans les jeux et le code numérique, où des millions de petits objets mettraient le ramasse-miettes sous pression. Voir structs.
Génériques : réifiés ou effacés
Java efface les arguments de type génériques à la compilation : à l'exécution, une List<Integer> n'est qu'une List, et List<int> n'est pas autorisé (on obtient des objets Integer boxés). C# conserve les arguments de type à l'exécution, donc List<int> stocke des ints bruts et le code peut demander ce qu'est T.
Sortie :
3 items of type Int32
1 items of type String
List`1
typeof(T) et new T() fonctionnent parce que le runtime connaît T. En Java, ce sont deux erreurs de compilation, et le contournement habituel consiste à faire circuler un objet Class<T>.
LINQ ou streams
Les deux langages ont une API fluide pour filtrer et transformer des collections. Celle de Java est l'API Streams (Java 8) ; celle de C# est LINQ (C# 3), qui a aussi une syntaxe de requête et fonctionne sur les bases de données via Entity Framework.
// Java
List<String> expensive = products.stream()
.filter(p -> p.getPrice() > 20)
.sorted(Comparator.comparing(Product::getPrice))
.map(Product::getName)
.collect(Collectors.toList());
Sortie :
Lamp, Chair
Total: 126
Les opérations se correspondent une à une (filter est Where, map est Select, collect(toList()) est ToList()), et les versions C# n'ont besoin ni de stream() ni de collecteur. Les objets new { Name = ..., Price = ... } sont des types anonymes, qui n'ont pas d'équivalent direct en Java.
Asynchrone et concurrence
C# a introduit async/await en 2012 : une méthode async renvoie une Task, et await la suspend sans bloquer de thread. JavaScript, Python et Rust ont ensuite adopté les mêmes mots-clés. Java a pris une autre voie : les chaînes de CompletableFuture et, depuis Java 21, les threads virtuels qui rendent peu coûteux le code bloquant ordinaire.
// C#
async Task<string> LoadAsync(HttpClient http, string url)
{
string body = await http.GetStringAsync(url);
return body.Substring(0, 100);
}
// Java 21 with virtual threads: plain blocking code on a cheap thread
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> client.send(request, BodyHandlers.ofString()));
}
Les deux approches tiennent la charge de nombreuses requêtes concurrentes. C# rend l'asynchronisme visible dans les signatures de méthode ; Java le cache dans le runtime.
Exceptions, opérateurs et petites différences
- Exceptions vérifiées. Java oblige une méthode à déclarer ou intercepter certaines exceptions (
throws IOException). C# n'a aucune exception vérifiée. - Surcharge d'opérateurs. C# permet aux types de définir
+,==,<et compagnie, c'est pourquoi l'arithmétique surdecimaletDateTimese lit naturellement. Java ne le permet pas (BigDecimal.add). - Virtuel par défaut. Les méthodes Java peuvent être redéfinies sauf si elles sont marquées
final; les méthodes C# doivent être marquéesvirtualpour être redéfinissables, et la redéfinition doit indiqueroverride. - Méthodes d'extension. C# peut ajouter des méthodes à des types existants (
"text".IsPalindrome()) ; Java ne le peut pas. - Types valeur nullables.
int?en C# est un int qui peut valoir null ; Java utilise le type boxéInteger. - Types non signés. C# a
uint,ulong,ushortet unbytenon signé ; lebytede Java est signé et, à part lechar16 bits, Java n'a pas de type entier non signé.
Écosystème, emploi et lequel apprendre
L'écosystème de Java est plus vaste dans le monde serveur open source : Spring, Kafka, Spark, Hadoop, Elasticsearch et la plupart des projets Apache sont en Java. Les applications Android s'écrivent en Kotlin ou en Java. C# a la pile la plus intégrée : un seul éditeur maintient le langage, le runtime, le framework web (ASP.NET Core), l'ORM (Entity Framework) et l'IDE principal (Visual Studio), et Unity le place au centre du développement de jeux.
Les deux langages ont de grands marchés de l'emploi, et l'équilibre entre eux dépend de la région et du secteur. C# est fort dans les entreprises bâties sur Microsoft et Azure, dans les logiciels de finance et de santé, et dans les studios de jeux vidéo.
Choisissez C# si vous voulez créer des jeux avec Unity, construire des applications de bureau Windows ou travailler dans une entreprise .NET. Choisissez Java si vous visez Android, le big data ou une entreprise dont le backend tourne sur la JVM. L'un comme l'autre enseigne les concepts dont vous aurez besoin pour le second : classes, interfaces, génériques, collections, exceptions et un runtime à ramasse-miettes.
Questions fréquentes
C# ressemble-t-il à Java ?
Oui, beaucoup. Tous deux sont des langages orientés objet, à typage statique et à ramasse-miettes, avec une syntaxe de style C, et compilés en bytecode pour une machine virtuelle. Un développeur Java peut lire du C# dès le premier jour. Les différences sont dans les détails : C# a les propriétés, les types valeur définis par l'utilisateur, les génériques réifiés, LINQ et async/await, tandis que Java a les exceptions vérifiées et un écosystème serveur open source plus vaste.
Faut-il apprendre C# ou Java en premier ?
Choisissez selon ce que vous voulez construire. C# pour les jeux Unity, les applications de bureau Windows et les entreprises bâties sur Microsoft et Azure. Java pour Android (avec Kotlin), les gros backends d'entreprise et les outils big data comme Kafka et Spark. Les langages sont assez proches pour que passer de l'un à l'autre plus tard prenne des semaines, pas des mois.
C# est-il plus rapide que Java ?
Ils sont dans la même catégorie de performances : les deux compilent en code natif via un JIT et utilisent des ramasse-miettes générationnels. C# offre plus de contrôle bas niveau grâce aux structs, à Span<T> et aux génériques sur des types valeur sans boxing, ce qui aide dans le code qui alloue beaucoup. Pour une application web typique, le framework et la base de données comptent bien plus que le langage.
C# a-t-il des exceptions vérifiées comme Java ?
Non. En C#, aucun type d'exception ne doit être déclaré ou intercepté ; la signature d'une méthode n'indique pas ce qu'elle lève. Les concepteurs ont estimé que les exceptions vérifiées menaient à des blocs catch vides et à des signatures fragiles. On documente les exceptions avec des commentaires XML /// <exception> à la place.
Qui offre le plus d'emplois, C# ou Java ?
Les deux ont de grands marchés de l'emploi, et celui qui compte le plus d'offres dépend du pays et du secteur ; regardez donc les annonces là où vous voulez travailler. C# est fort dans les entreprises Microsoft, la finance, la santé et les studios de jeux vidéo, Java dans les grandes banques, les télécoms, les backends e-commerce et Android.