Passer au contenu principal

Je suis parfaitement conscient qu’en écrivant cet article je marche sur des oeufs, ou plutôt je risque de me faire flamer par les java-istes et les césharpeux. Mais bon des développeurs de la communauté JobProd me l’ont demandé, alors je m’exécute. Et puis bon à l’heure où j’écris cet article il est 21h, j’ai donc le droit de lancer un sujet à trolls non ? :-p

On ne va pas présenter Java et .Net, mais plutôt comparer les deux sur différents points, afin que vous puissiez vous faire une idée. Un point très important toutefois : la situation évolue très rapidement, en particulier pour .Net, aussi il y a de fortes chances que ce que j’écris maintenant soit caduque d’ici un ou deux ans.

Applications serveur

Aujourd’hui l’essentiel des développements que nous faisons peut se diviser en trois catégories :

– Les applicatifs côté serveur, qui contiennent en principe le code métier.
– Les clients légers, en Javascript donc hors scope. Pitié ne procédez pas comme au début des années 2000 où la partie HTML/JS formait un tout indivisible avec le code côté serveur !
– Les applications mobiles.
Ici on va se concentrer uniquement sur les applications serveur, le reste étant à peu près hors scope même si je vais encore me faire insulter par les développeurs mobile.

La plateforme serveur web pour .Net est ASP.Net, alors que pour Java c’est JEE. Sauf que pour l’instant les builds officielles de .Net fonctionnent uniquement sous Windows, bien que depuis peu ce soit en train de changer pour .Net core. Alors bien sûr on a Mono aussi sur les vrais systèmes, mais celui-ci peut avoir des comportements différents des builds .Net, donnant parfois des résultats imprévisibles. Vous ne me croyez pas ? Un collègue a dû faire tourner un code Java avec un StringBuilder sur une JVM IBM. Eh bien ce code ne fonctionnait pas, car il existe dans l’implémentation d’IBM une méthode privée append qui prend en paramètre exactement le type d’un objet que le code du collègue appelait dans son append en pensant faire un append(java.lang.Object). Et donc sur la JVM Oracle tout allait bien alors que sur celle d’IBM c’était un access denied…

En Java par contre la JVM de référence est OpenJDK, une implémentation libre et gratuite. Celle-ci est disponible pour de nombreux systèmes et de nombreuses architectures, dont Windows, Linux, AIX, Solaris et bien d’autres. D’autre part les serveurs applicatifs JEE sont foison étant donné que JEE n’est qu’une spécification, ensuite à charge à ceux qui le souhaitent de l’implémenter. Enfin bref au moment du déploiement si vous êtes sous .Net bien qu’il soit possible de faire fonctionner le code sur autre chose que du Windows on s’expose à des problèmes alors que pour Java on peut faire tourner le code sur toutes les plateformes les plus répandues.

D’autre part les librairies et frameworks côté Java sont légion. Il y a Spring, Hibernate et bien d’autres. Alors beaucoup ont été portées sous .Net mais ce n’est pas le cas de toutes.

Bref si vous devez coder côté serveur privilégiez Java.

Applications clientes et bureau

Les applications clientes côté Java n’ont jamais vraiment percé, contrairement à celles côté .Net. De même pour les applications de bureau. Cela s’explique par de nombreuses raisons pour Java, notamment le fait que la JVM soit plutôt longue à démarrer, et que les applications Java soient pendant longtemps restées moches même si ça a changé depuis JavaFX 2.

Les applications .Net peuvent être écrites soit en utilisant les WinForms, auquel cas elles sont portables, soit en Xaml. Ce dernier est le moyen recommandé par Microsoft pour bien séparer le code de la présentation, tout en ayant accès à des effets graphiques sympathiques. Malheureusement l’utiliser condamne aussi, à l’heure actuelle, la portabilité de vos applications.

Il n’empêche que les applications graphiques .Net sont plus jolies à regarder que celles en Java, et démarrent plus rapidement.

Bref si votre application doit être déployée sur des postes de travail choisissez clairement .Net.

Les environnements de développement

Côté .Net la chose est vite réglée. Il y a Visual Studio, et les autres dont SharpDevelop et son dérivé MonoDevelop qui sont franchement à la ramasse. Par ailleurs il faut reconnaître que le premier est franchement bien foutu, et qu’il est très plébiscité des développeurs pour cette raison. Il présente néanmoins un inconvénient de taille : il n’est disponible que sous Windows et rien d’autre, ce qui fait que si vous développez une application destinée au multiplateforme ce n’est vraiment pas top pour déboguer les différences de comportement.

Côté Java par contre il existe de nombreux IDE et la plupart sont multiplateformes. Parmi les plus connus il y a Eclipse, NetBeans et IntelliJ IDEA. Bref on a l’embarras du choix, et pour les warriors on peut aussi coder en Java avec vim ou Emacs, j’en ai d’ailleurs fait aujourd’hui. Vous me direz pour ce dernier point c’est aussi possible en .Net. Mais franchement, utiliser un débogueur en dehors d’un IDE pour Java ou .Net relève franchement de l’auto-punition.

Bref si vous voulez une techno qui vous permette de développer sur une plateforme aussi proche que possible de votre cible préférez Java, sauf dans le cas où votre cible est Windows.

Le langage en lui-même

Pour .Net on va ici parler uniquement du C#, tandis que pour Java on va évoquer uniquement le langage Java en lui-même. Chacune de ces plateformes supporte différents langages, mais je ne m’étendrai pas dessus. Qui sait, peut-être qu’un jour un petit malin développera un compilateur Brainfuck pour chacune des plateformes, quoi qu’il semblerait que ça existe déjà pour la JVM. 😀


System.out.println("Hello I am Java, and I'm better than C#");
Console.WriteLine("Hello I am C#, and I'm better than Java");

Bref autant faire tomber tout de suite le masque : la syntaxe du C# est vraiment plus sympa que celle de Java. C’est particulièrement visible pour la définition des propriétés, où en Java on est obligé de passer par d’infâmes getters et setters qui donne un look objet à vos classes sans pour autant que ce soit le cas. Néanmoins il y a des trucs plus discutables parmi les ajouts syntaxiques de .Net dont les classes partial. Par ailleurs un gros manque de .Net est l’absence de visibilité privée au namespace (package en Java, cette dernière étant pourtant si pratique notamment pour les adeptes des tests unitaires dont je fais partie. On pourra aussi fouetter pendant des siècles entiers les designers de C# pour avoir autorisé l’utilisation du mot-clef var.

Par contre question librairie standard et bibliothèques externes c’est clairement l’inverse. Pour vous en convaincre regardez la librairie standard. Si vous voulez déclarer une liste en Java il suffit d’utiliser l’interface List, alors qu’en .Net l’interface IList ne contient qu’une partie des méthodes de la classe List. Bref pour ce dernier vous serez fréquemment obligé de déclarer directement l’implémentation de la classe utilisée, et ce n’est franchement pas top au niveau objet. Et d’autre part la communauté a crée bien plus de librairies et frameworks au niveau de la JVM qu’au niveau de .Net, une des raisons est que pendant longtemps ce dernier n’était vraiment pas portable.

Bref en terme de langage les deux se valent.

La maintenabilité des projets dans le temps

La JVM garantit depuis longtemps que tant que vous n’utilisez que des méthodes de l’API Java, autrement dit pas de méthode des paquets sum.* et com.sun.* un code qui fonctionne sur une version donnée de Java fonctionnera également sur les versions ultérieures, sans nécessiter de recompilation. Evitez tout de même d’utiliser les méthodes en deprecated, car de temps en temps ils passent un coup de balai. Cette approche comporte néanmoins des problèmes, notamment quand il a fallu ajouter le support des génériques en Java.

En C# c’est par contre plus compliqué. Un code compilé pour .Net 2.0 fonctionnera sans problème sur .Net 3.5 mais devra être recompilé pour fonctionner sur la version 4, en priant pour que la compilation se fasse bien. Le vrai souci est que par exemple .Net 1.x n’existe pas sous Windows 10, et je ne suis pas sûr non plus que la version 3.5 existe (si un dieu du C# passe qu’il confirme). Enfin bref à un moment où à l’autre on peut être obligé de recompiler, ce qui peut augmenter de fait les coûts de maintenance. Mais d’un autre côté ça permet d’éviter de traîner des boulets comme le support des génériques de la JVM.

Bref je dirais légèrement Java sur ce point, mais légèrement seulement car les deux approches se défendent.

En bref…

Pour résumer le principal point à prendre en compte est le type d’application que vous souhaitez développer. Si c’est du serveur partez sur Java, maintenant si c’est du client lourd ou une application de bureau préférez C#.

Cet article vous a plu ? Vous aimerez sûrement aussi :

Julien
Moi c’est Julien, ingénieur en informatique avec quelques années d’expérience. Je suis tombé dans la marmite étant petit, mon père avait acheté un Apple – avant même ma naissance (oui ça date !). Et maintenant je me passionne essentiellement pour tout ce qui est du monde Java et du système, les OS open source en particulier.

Au quotidien, je suis devops, bref je fais du dév, je discute avec les opérationnels, et je fais du conseil auprès des clients.

Son Twitter Son LinkedIn

Rejoignez la discussion 6 Commentaires

  • Pascal Craponne dit :

    Bonjour,

    cet article appelle un certain nombre de précisions concernant .NET (je ne connais pas Java).
    Tout d’abord, XAML est un langage et non une technologique de présentation en soi. Avec du XAML, vous pouvez à ce jour faire du WPF (qui est le plus complet), Silverlight (qui a l’avenir que l’on connait) ou UWP (Universal Windows Platform, une version allégée censée tournée sur PC mais aussi sur téléphones Windows 10… Ceux que personne n’utilise ou même XBOX). Ces trois technologies, toutes pilotés via XAML sont au final assez différentes, en termes de contrôles et également de contraintes.
    Concernant les environnements de développement, Microsoft propose maintenant Visual Studio Code, un outil tournant sur plusieurs plateformes. Plus de détails ici: https://www.visualstudio.com/products/code-vs
    Ensuite, il est dommage de considérer que le framework .NET se programme en C#. C’est effectivement le langage le plus utilisé. Je ferai ici l’impasse sur VB.NET, mais il y a d’autres langages comme F# ou IronPython, notamment. Et il ne faut pas oublier non plus ici managed C++ qui permet de générer soit du code pur .NET soit du code mixte (natif et .NET).
    En lisant votre critique du var, j’aimerais savoir ce que vous reprochez à ce mot-clé qui a été introduit dans le but spécifique de simplifier l’écriture lorsque LINQ a été ajouté au langage. N’étant utilisant que pour des variables locales, il facilite la lecture et ne nuit pas aux déclarations d’interface (puisqu’il n’est pas autorisé).
    Idem concernant IList, c’est parce que cette interface couvre le List mais aussi les tableaux (autrement dit un tableau A[] implémenterai IList). Donc forcément IList n’est pas aussi complet que List… Si vous voulez utiliser l’ensemble des fonctionnalités, utilisez la classe. Je trouve donc votre jugement un peu hâtif sur ce point.
    Et non, un code C# compilé pour du .NET 2 n’aura pas besoin d’être recompilé pour tourner avec du 4, sauf évidemment si vous voulez en changer les fonctionnalités. La CLR4 interagit avec la CLR2, ce qui permet de gérer un paquetage hétérogène en terme de versions.
    Je voulais terminer sur mono. Mono tourne « différemment » si l’on veut: mon expérience personnelle m’a montré qu’en réalité le framework mono est plus strict que .NET (ils appliquent réellement la documentation), donc si l’on ne fait pas de supposition sur un comportement en .NET, cela fonctionnera sans problème sur mono (pour info, j’ai porté un projet de 2 ans pur .NET sur mono en moins d’une semaine). De plus, depuis l’ouverture du core .NET, mono l’intègre (ou va l’intégrer, je n’ai pas suivi en détail), donc les frameworks vont se rapprocher en comportement.

    Merci pour cet article qui permet de stimuler son esprit critique 😉

  • gojul dit :

    Merci pour les précisions.

    Alors pour quelques points :
    1/ le souci du var est qu’on le voit ensuite utilisé à tort et à travers. D’un côté dans ce cas il aurait peut-être mieux valu retourner une liste d’Object.

    2/ Pour IList merci de l’éclaircissements. Mais dans ce cas il aurait pu être opportun de faire une interface implémentée par List qui hérite de IList, Itruc et Imachin. Ca permettait d’éviter de balancer directement des implémentations. Alors après c’est clair que c’est plus facile à dire qu’à faire.

    Et oui .Net permet de lancer différents langages, comme la JVM à ce niveau.

    Pour Mono enfin merci pour les précisions. Par contre il faut reconnaître que Monodevelop reste une daube. Dommage car pouvoir développer du .Net directement sur ma Debian m’intéresserait fortement. Là je suis obligé d’utiliser une VM ou une autre machine.

  • JB dit :

    Je trouve dommage que cet article ait été écrit par un javaiste qui ne connait pas vraiment .Net. Je pense qu’il aurait été mieux de trouver une personne connaissant les deux environnements même si c’est très rare je l’accorde

    Tout d’abord je pense qu’il y a beaucoup d’aspects niveau business qui n’ont pas été pris en compte dans l’analyse, notamment l’environnement existant, le métier (certains secteurs sont très liés aux technologies Microsoft ou inversement), le prix, les développeurs de l’entreprise et leurs connaissances existantes… Bref je ne parlerai pas de ce coté là mais vais apporter quelques précisions en tant que développeur .Net.

    Partie serveur :

    « D’autre part les serveurs applicatifs JEE sont foison étant donné que JEE n’est qu’une spécification, ensuite à charge à ceux qui le souhaitent de l’implémenter »

    Cet argument peut-être utilisé également un contre argument… L’avantage du .Net c’est sa stabilité. Pas de ouai mais ça marche pas sous JBoss par contre ça fonctionnait sous Tomcat.

    « D’autre part les librairies et frameworks côté Java sont légion. Il y a Spring, Hibernate et bien d’autres. Alors beaucoup ont été portées sous .Net mais ce n’est pas le cas de toutes. »

    J’aimerais bien savoir ce qui manque de la stack Java sur .Net ? Je tenais également à préciser que les technos Java ayant été portées sous .Net comme Spring.Net ou NHibernate ne sont souvent pas les meilleures et ne sont souvent plus utilisées sur de nouveaux projets.

    Partie client lourd :

    Plutôt d’accord avec l’analyse. (WinForm c’est complètement obsolète par contre)

    Partie IDE :

    Je pense que cette partie aurait pu être développée également. Il aurait fallu évoquer les prix par exemple. Pourquoi ne pas également parler ici des environnements d’intégration continue ? De plus niveau fonctionnalités il y a quand même un fossé entre un Visual Studio et un Eclipse et ne parlons pas de stabilité ou de rapidité (je n’ai pas dû ouvrir un Eclipse depuis 2 ans mais je me souviens que c’était une plaie à ce niveau là)

    Langage :

    Là je ne suis pas du tout d’accord. Pour moi C# est bien au dessus. Et merci à Java 8 pour avoir apporter beaucoup de belles choses comme les lambdas expressions pour réduire les différences. En C#, on a async/await, Linq, les délégués, les méthodes d’extensions… Le langage est beaucoup plus riche. (Là j’ai vraiment testé les deux, j’ai fait beaucoup de Java étant étudiant, même si je sais qu’il y a eu des améliorations avec Java 8 notamment)

    De plus je trouve les arguments contre C# un peu léger comme le mot clé var qui a été introduit pour linq notamment (Oui ça n’existe pas sous Java). De plus ce mot est utilisable uniquement au niveau d’une fonction, il suffit de savoir bien l’utiliser. Pour info var n’a rien à voir avec object. Le typage est déterminé à la compilation. Ce qui permet d’accéder aux différentes fonctions/propriétés des objets.

    Pour l’argument de IList ou List. Je suis un inconditionnel de l’injection de dépendance et il ne m’est jamais arrivé un cas ou j’ai dû utiliser une List comme propriété d’une classe ou paramètre d’une fonction. C# applique bien le principe de ségrégation des interfaces.

    Maintenabilité des projets dans le temps

    Je suis plutôt d’accord avec le commentaire de Pascal Craponne. Sinon de mon point de vue je pense sincèrement qu’il faut inciter les développeurs à être à jour au niveau des librairies/frameworks et de ne pas se contenter d’un « ça marche » et attendre 5 ans avant de commencer à faire quelque chose. Le coût de maintenance sera beaucoup plus grand au final.

    Bref je pense que ce genre d’article est délicat à écrire. Et hormis pour troller ce n’est pas génial. En revanche j’aimerais bien avoir l’avis d’une personne travaillant au quotidien avec les deux technos. Mais je doute que ce soit simple à trouver…

    Bonne continuation à tous,

  • « Par ailleurs un gros manque de .Net est l’absence de visibilité privée au namespace (package en Java, cette dernière étant pourtant si pratique notamment pour les adeptes des tests unitaires dont je fais partie. »

    Faux. Il existe le mot-clé « internal » en C# pour justement restreindre une propriété, une méthode ou même une classe à un namespace.
    D’ailleurs, si seul le mot « class » apparaît, elle est par défaut internal.
    Il faut donc préciser « public class » pour que cette dernière soit visible pour les autres namespaces.

    • gojul dit :

      Nope, le mot clef « internal » sert pour la visibilité à l’intérieur de l’assembly, pas du namespace. En java un package est à peu de choses près équivalent à un namespace, pas à un assembly. Ce dernier serait équivalent au JAR. Depuis Java 9 il y a le projet Jigsaw pour avoir un mécanisme équivalent à internal en Java, mais on va dire gentiment qu’en dehors de la JVM ce n’est pas au point tellement c’est facile à contourner.

  • Une précision complémentaire à plusieurs points :
    « En C# c’est par contre plus compliqué. Un code compilé pour .Net 2.0 fonctionnera sans problème sur .Net 3.5 mais devra être recompilé pour fonctionner sur la version 4, en priant pour que la compilation se fasse bien. »
    => Faux Si le programme est compilé en .NET 2.x et que par exemple :
    – .NET 2.x et .NET 4.x sont installés sur la même machine, le runtime 2.x sera utilisé
    – Si seule la version 4.x est installée, le code sera exécuté à l’aide du runtime 4.x sans soucis

    « Le vrai souci est que par exemple .Net 1.x n’existe pas sous Windows 10, et je ne suis pas sûr non plus que la version 3.5 existe (si un dieu du C# passe qu’il confirme). »
    => Le runtime est fait pour exécuter n’importe quel code fait avec n’importe quelle version de .NET. Seules exceptions faites avec .NET Core et .NET Standard.

    « Enfin bref à un moment où à l’autre on peut être obligé de recompiler, ce qui peut augmenter de fait les coûts de maintenance. Mais d’un autre côté ça permet d’éviter de traîner des boulets comme le support des génériques de la JVM. »
    => Faux. Le compilateur C# compile en MSIL et non en binaire directement. C’est le runtime qui se charge de compiler ce langage MSIL en code natif lors de l’exécution du programme.

    Depuis que je travaille avec la plateforme .NET, il ne m’est jamais arrivé de devoir recompiler un programme pour l’exécuter.
    On fait des mises à jour de version forcément, mais il est tout à fait possible d’exécuter un programme fait avec une ancienne version .NET dans un runtime .NET plus récent.

    Pour la portabilité, je conçois que l’article date un petit peu mais avec .NET Core et Visual Studio Code, il est tout à fait possible de développer et d’exécuter des applications .NET Core sous Windows, Linux, Docker etc etc.

Laisser un commentaire