Neal Gafter quitte Google... Pour Microsoft

Les rumeurs courent depuis plusieurs jours maintenant, et c'est maintenant certain. Neal Gafter, un des "grands" du monde Java, viens de quitter Google pour aller travailler chez Microsoft.

Neal Gafter travaille depuis longtemps pour le monde Java. Il a notamment dirigé les évolutions du langages et des outils (java, javac, javah et javap) de la version 1.3.1 à la version 1.5.0 du JDK. Plus récemment, il a également contribué à Java 7, et fait entre autres partie de l'équipe à l'origine des closures BGGA.

Maintenant chez Microsoft, il travaille sur les langages de la plate-forme .NET, et en particulier le langage C#.

Beaucoup en parlent comme d'une mauvaise nouvelle pour le monde Java, il reste à voir ce que ce changement va nous apporter...

Permalink  |  Commentaires (0)

Java/.NET : Types de données

Dans ce second billet de la série "Java/.NET", nous allons parler de toutes les différences touchant aux types de données.

Fichiers sources

En Java, le compilateur n’autorise qu’une seule et unique classe publique par fichier source. De plus, la classe publique d’un fichier source doit posséder exactement le même nom que le fichier dans lequel elle se trouve.

En C#, les restrictions comme celles-ci n’existent pas. Il est possible de déclarer plusieurs classes publiques au sein du même fichier, et aucune vérification n’est faite quand au nom du fichier contenant les classes.

Types primitifs - types valeurs

En Java comme en C#, il existe un type de données particulier : leur valeur est directement stocké dans une zone mémoire appelée la pile. De plus, ces différents types de données sont directement passés par valeur.

Ils peuvent représenter une valeur "basique", à savoir :
  • Un nombre (entier ou à virgule flottante)
  • Un caractère
  • Un booléen

En Java, ces types de données qui sont appelés des types primitifs. Il s’agit des seuls types de données qui ne sont pas des objets, c'est-à-dire qu’ils ne possèdent aucune méthode. Pour palier à cet inconvénient, il existe des types dits wrappers, qui sont des équivalents objets de ces types primitifs.

En C#, ces types sont appelés les types valeurs. Ils résident également sur la pile, mais ce sont cependant des objets. Chaque type valeur possède un alias, qui permet de faciliter l’appel de ces types dans le code. Par exemple, le type valeur Int32 possède un alias int. Ces alias seront convertis au moment de la compilation.

A noter également qu’en C#, les chaînes de caractères et les énumérations ont la particularité d’être des types valeur. Au contraire, les chaînes de caractères et les énumérations en Java sont des objets, et résident sur le tas.

Types références

Chacun des deux langages définit un autre type de variables : les types références.

Contrairement aux types primitifs (ou types valeurs), ils sont passés par référence lors des différents appels de méthodes. Ils représentent en général des types complexes, que nous allons définir nous même. De plus, la valeur de ces types de données est stockée sur le tas, et la pile ne contient qu’une référence vers ces objets.

En Java, chaque type primitif possède un équivalent en type référence. Ce sont les types wrappers. Ces objets sont des objets comme tous les autres objets Java. Leur valeur réside sur le tas et ils sont passés par référence lors des différents appels de méthodes. Depuis Java 1.5, la conversion entre les types primitifs et types wrapper est automatique.

En C# comme en Java, les classes sont des types références.

Structures

Le langage C# introduit un type de données qui n’existe pas en Java : le type structure. Les structures sont un type de données semblable aux classes, sauf qu’elles sont de types valeur, et non de type référence.

Cette différence implique que les structures sont stockées sur la pile (et non sur le tas, contrairement aux objets), et qu’elles sont passées par valeur en paramètre aux méthodes.

De par leur statut particulier, les structures ont cependant quelques fonctionnalités en moins par rapport aux classes. Il est impossible par exemple d’hériter d’une structure en C#.

Enumérations

En Java, les énumérations sont des objets. Comme pour les objets, il est possible de leur définir des attributs, des méthodes, et même des constructeurs.

Contrairement à cela, en C#, les énumérations sont de type valeur. Les énumérations correspondent à des entiers codés sur 8, 16, 32 ou 64 bits. Il est également possible d’assigner n’importe quelle valeur numérique à une énumération (y compris des valeurs non définies dans l’énumération), ainsi que de combiner plusieurs valeurs pour une même énumération grâce à l’opérateur | (bitwise or).

Espaces de nommages

Lors du développement d’applications, il arrive que plusieurs structures de données (classes, interfaces, énumérations...) possèdent le même nom. Afin d’éviter les collisions de noms ainsi générées, chaque langage à mis en place sa propre solution : les espaces de nommages.

En Java, un espace de nommage s’appelle un package. Un package doit être déclaré en début de tout fichier source grâce au mot clé package suivi du nom du package, et s’applique à tout le fichier. Il est possible d’accéder à des classes appartenant à d’autres packages grâce au mot clé import, suivi du nom de la classe à importer. Il est également possible d’importer toutes les classes d’un package en utilisant l’étoile (*).

En C#, un espace de nommage s’appelle un namespace. Un namespace est un bloc de code, noté grâce au mot clé namespace, suivi du nom du namespace. Il est possible d’utiliser des classes appartenant à d’autres espaces de noms grâce au mot clé using, suivi du nom de l’espace de nom à utiliser.

Voici par exemple la déclaration de deux classes dans un espace de nommage, en Java (à gauche) et en C# (à droite) :
package ns;

class Toto {
}

class Tata {
}

namespace Ns
{
    class Toto
    {
    }
    class Tata
    {
    }
}

Types génériques

Java et C# implémentent tous les deux les types génériques. Si l’utilisation est similaire dans les deux langages, leurs implémentations sont cependant très différentes.

Premier point, les types génériques en Java n’acceptent pas les types primitifs, alors que l’implémentation en C# accepte les types valeurs.

Second point, les génériques en Java sont implémentés selon une technique dite du type erasure. Derrière ce nom effrayant se cache un concept simple : les génériques en Java sont évalués à la compilation, toute trace de type générique n’existe plus à l’exécution. C’est le compilateur qui va se charger de transformer les types génériques en leurs opérations équivalentes (principalement du transtypage et des vérifications de types), et supprimer toute trace de leur passage.

Contrairement à cela, les génériques en C# persistent à l’exécution, et sont interprétés par l’environnement d’exécution. Il est donc possible de connaître le type générique d’une classe ou d’une méthode lors de l’exécution.

Les conséquences sont alors multiples. Par exemple, en C#, il est possible de créer une instance d’un type générique, et des tableaux de types génériques, choses qui sont impossibles à faire en Java, principalement à cause du type erasure.

Autre différence importante, il est possible d’effectuer des vérifications plus poussées sur les types utilisés en tant que types génériques dans le langage C#. Par exemple, en C#, il est possible de définir une contrainte « Cette classe utilise un type T, qui doit posséder un constructeur par défaut », contrainte qui est impossible en Java.


Voilà donc la fin de cette liste de différences entre Java et C# en ce qui concerne les types de données.

Le prochain billet portera sur les opérateurs, et devrait parler de deux fonctionnalités présentes en C# et inexistantes en Java : la surcharge des opérateurs et les indexeurs.

PS : Ceci était de 42ème billet de ce blog ;-)

Permalink  |  Commentaires (1)

Java/.NET : Concepts élémentaires

Dans ce premier billet de la série consacrée aux différences entre Java et .NET, nous allons voir les concepts élémentaires des deux plateformes.

Les concepts élémentaires au niveau des deux technologies sont très similaires. Les deux s’appuient sur le même principe : la compilation est effectuée vers un langage intermédiaire. Ce langage intermédiaire est proche du langage machine, mais indépendant de l’architecture et du système. Il sera ensuite exécuté par une machine virtuelle au moment de l’exécution du programme. Ce principe permet d’assurer une certaine portabilité entre les différents systèmes d’exploitation et les différentes architectures matérielles.

Compilation

Le compilateur C# s’appelle CSC (C-Sharp Compiler). Il est chargé de traduire le code source C# en code MSIL (Microsoft Intermediate Language), un langage intermédiaire qui sera ensuite exécuté par l’environnement d’exécution de la plateforme .NET.

Le compilateur Java est appelé Javac (Java Compiler), et son rôle est de transformer le code source Java en ByteCode, qui est le langage intermédiaire de la plateforme Java.

Les deux compilateurs comportent également des fonctionnalités plus poussées. Chacun des compilateurs est capable, par exemple, d’optimiser le code source au moment de la compilation afin d’en améliorer les performances. Il n’y a pas de différence majeure à ce niveau là.

Environnement d'exécution

L’environnement d’exécution .NET est construit autour de la CLR (Common Language Runtime). Il s’agit de la machine virtuelle chargée d’exécuter le code MSIL généré par le compilateur.

De son coté, l’environnement d’exécution Java tourne autour de la JVM (Java Virtual Machine). Son rôle sera d’exécuter le ByteCode, afin de permettre l’exécution de nos programmes.

Les deux machines virtuelles sont très proches, et sont conçues de manière semblable. Les deux embarquent un chargeur de classe (Class Loader), un compilateur JIT (Just In Time) qui transforme le code intermédiaire en code natif afin d’accélérer l’exécution, d’un ramasse miettes (Garbage Collector) qui libère la mémoire qui n’est plus utilisée par le programme, ainsi que d’autres composants permettant d’assurer le bon fonctionnement de nos logiciels (sécurité des applications, interaction avec le système, ...).

La principale différence au niveau de l’environnement d’exécution est la portabilité de celui-ci. Alors qu’il existe une machine virtuelle Java pour la plupart des systèmes d’exploitation du marché, la CLR de Microsoft est développée uniquement pour Windows. Même si Microsoft à fait des efforts ces derniers temps pour porter la CLR vers d’autres systèmes (notamment grâce au projet Mono), la plateforme .NET est loin de posséder la même portabilité que la plateforme Java.

Bibliothèques de base

Chacun des deux environnements embarque une bibliothèque de base. Ces bibliothèques sont des ensembles de composants prêts à l’emploi, qui permettent de faciliter le développement d’applications. Sur les deux plateformes, nous retrouvons des composants semblables : interfaces graphiques, gestions des entrées-sorties, gestion de l’accès aux données (bases de données, annuaires LDAP, ...), gestion des processus...

Les principales différences entre les deux ensembles de bibliothèques embarquées se trouvent dans les noms attribués aux classes et aux méthodes, la plupart des composants présents dans l’une trouvant son équivalent dans l’autre.


Ainsi s'achève ce premier billet portant sur les concepts élémentaires de chacune des plateforme. Comme nous l'avons vu, les différences sont assez minimes, et les principes globaux sont communs aux deux environnements.

Dans le prochain billet, nous aborderont les différences qui touchent aux types de données (types primitifs/valeurs, types références, énumérations, ...).

Permalink  |  Commentaires (0)

Java/.NET : Introduction

Ça y est !

Je viens de finir une (longue) période de formation. J'ai été invité à suivre une formation de trois semaines, qui s'est terminée aujourd'hui, au SUPINFO Training Center, portant sur les technologies .NET, et en particulier :
  • Framework .NET 2.0, base du développement d’application
  • Windows Forms, Accés aux données avec Visual Studio 2005
  • Création et programmation d’une application Web ASP.NET 2.0

Étant formateur Sun (et donc, Java), le but de cette formation était de comparer les deux technologies. Loin de moi l'idée d'abandonner le Java pour me mettre au .NET (j'ai déjà vendu mon âme :P). Il s'agissait là d'une ouverture d'esprit, de la découverte d'une autre technologie afin de mieux pouvoir défendre la sienne.

La formation en elle-même était très intéressante. Les deux premières semaines (Framework 2.0 et Windows Forms) furent dispensées par Julien Corioland, la dernière par Maxime Schneider (je tiens à les remercier tous les deux). Le seul point noir que j'aurais à souligner concerne le cursus en lui même, qui portait sur le framework 2.0 alors que la version la plus récente est la 3.5, et que les changement entre les deux versions sont importants (WPF, WCF, Linq, ...).

J'ai déjà fait un petit résumé de cette formation en 140 caractères (à la demande de Julien Quéré) :
Il y a quelques fonctionnalités interessantes (properties, delegates, ...), mais mon coeur reste chez Java :-)

Je pense que cette citation est celle qui résume le mieux ce que je pense de ces trois dernières semaines.

Je vais maintenant entamer (continuer serait plus exact, j'ai déjà un peu commencé :P) un gros feedback sur ce que j'ai retenu de cette formation : les principales différences entre Java et .NET.

Ceux qui me connaissent le savent, je suis un excellent trolleur. Et ils n'ont pas complètement tort. Je vais cependant essayer d'être le plus objectif possible :-)

Ce billet est donc le premier d'une série qui relatera les différences que j'ai constaté, retenu, et qui ont, à mon avis, leur importance, pour le développeur qui souhaite comparer les deux plateformes de développement.


Petite remarque au passage : Ce billet était aussi le billet de la rentrée. En effet, je n'avais pas publié de billets, pour des raisons diverses et variées, depuis environ deux mois. La rentrée étant arrivée, mon rythme de publication devrait redevenir un peu plus... soutenu :-)

Permalink  |  Commentaires (3)