Je suis nouveau sur .Net et j'essaie d'abord de comprendre les bases. Quelle est la différence entre le bytecode MSIL et Java?
Réponses
Trop de publicités?D'abord, laissez-moi vous dire que je ne pense pas que les différences subtiles entre le bytecode Java et MSIL est quelque chose qui devrait déranger un novice .NET développeur. Ils servent tous les deux le même but, à savoir la définition d'un abrégé de la machine cible qui est une couche au-dessus de la machine physique utilisé dans la fin.
MSIL et le bytecode Java sont très semblables, en fait, il existe un outil appelé Sauterelle qui se traduit par MSIL pour le bytecode Java, je faisais partie de l'équipe de développement pour la Sauterelle, donc je peux partager un peu de mes (fanée) de la connaissance. Veuillez noter que j'ai arrêté de travailler sur ce autour de lors de .NET framework 2.0 est sorti tellement de certaines de ces choses ne peut pas être plus vrai (si s'il vous plaît laissez un commentaire et je vais le corriger).
- .NET permet de types définis par l'utilisateur qui se trouvent sur la pile (
struct
). - .NET prend en charge non signé types, ce qui rend le jeu d'instructions un peu plus riche.
- Java comprend la spécification d'exception de méthodes dans le bytecode. Bien que la spécification d'exception est généralement appliquée par le compilateur, il peut être exécuté par la JVM si un chargeur de classe autre que celui par défaut est utilisé.
- .NET génériques sont exprimés en IL alors que Java génériques utilisez uniquement le type d'effacement.
- .NET attributs n'ont pas d'équivalent en Java (est-ce toujours le cas?).
- .NET
enums
ne sont pas beaucoup plus que les wrappers autour de types d'entiers alors que Javaenums
sont à peu près à part entière classes (grâce à Internet Ami pour les commentaires). - .NET a
out
etref
paramètres.
Il y a d'autres différences de langue, mais la plupart d'entre eux ne sont pas exprimées à l'octet de code de niveau, par exemple si la mémoire est de Java non-static
les classes internes (qui n'existent pas dans .NET) ne sont pas un code binaire en fonction, le compilateur génère un argument supplémentaire à l'intérieur du constructeur de la classe et passe à l'objet extérieur. La même chose est vraie pour les .NET des expressions lambda.
CIL (le vrai nom de MSIL) et le bytecode Java sont plus les mêmes qu'ils sont différents. Il y a quelques différences importantes:
1) CIL a été conçu dès l'origine pour servir de cible pour plusieurs langues. En tant que tel, il prend en charge beaucoup plus riches type de système, y compris les entiers signés et non signés, les types de valeur, les pointeurs, les propriétés, les délégués, les événements, les génériques, un objet avec une seule racine, et plus encore. CIL qui prend en charge les fonctionnalités pas requis lors de la première CLR langages (C# et VB.NET) tels que les fonctions globales et de la queue-appel d'optimisations. En comparaison, le bytecode Java a été conçu comme une cible pour le langage Java et reflète beaucoup de contraintes trouvé en Java lui-même. Il serait beaucoup plus difficile d'écrire C ou de l'utilisation de bytecode Java.
2) CIL a été conçu pour s'intégrer facilement dans les bibliothèques natives et code non managé
3) le bytecode Java a été conçu pour être interprété ou compilé tout CIL a été conçu en supposant compilation JIT. Cela dit, la mise en œuvre initiale de Mono utilisé les services d'un interprète à la place d'une équipe commune d'enquête.
4) CIL a été conçu (et spécifié) d'avoir un homme de lecture et d'écriture de l'assemblée forme de langage que les cartes directement sur le bytecode forme. Je crois que le bytecode Java est (comme son nom l'indique, destiné à être uniquement lisible par la machine. Bien sûr, le bytecode Java est relativement facile à décompilé en arrière à l'original Java et, comme indiqué ci-dessous, il peut aussi être "démonté".
Il est à noter que la JVM (la plupart d'entre eux) est plus optimisé que le CLR (l'un d'eux). Donc, la performance brute pourrait être une raison de préférer le ciblage de bytecode Java. C'est un détail d'implémentation.
Certaines personnes disent que le bytecode Java a été conçu pour être multi-plateforme, tandis que CIL a été conçu pour Windows uniquement. Ce n'est pas le cas. Il y a quelques "Windows"ismes dans le .NET framework, mais il n'en existe pas dans le CIL.
Comme un exemple de nombre de point 4) ci-dessus, j'ai écrit un jouet Java à CIL compilateur a tout à l'arrière. Si vous nourrissez ce compilateur Java suivantes du programme:
class Factorial{
public static void main(String[] a){
System.out.println(new Fac().ComputeFac(10));
}
}
class Fac {
public int ComputeFac(int num){
int num_aux ;
if (num < 1)
num_aux = 1 ;
else
num_aux = num * (this.ComputeFac(num-1)) ;
return num_aux ;
}
}
mon compilateur va cracher le suivant CIL:
.assembly extern mscorlib { }
.assembly 'Factorial' { .ver 0:0:0:0 }
.class private auto ansi beforefieldinit Factorial extends [mscorlib]System.Object
{
.method public static default void main (string[] a) cil managed
{
.entrypoint
.maxstack 16
newobj instance void class Fac::'.ctor'()
ldc.i4 3
callvirt instance int32 class Fac::ComputeFac (int32)
call void class [mscorlib]System.Console::WriteLine(int32)
ret
}
}
.class private Fac extends [mscorlib]System.Object
{
.method public instance default void '.ctor' () cil managed
{
ldarg.0
call instance void object::'.ctor'()
ret
}
.method public int32 ComputeFac(int32 num) cil managed
{
.locals init ( int32 num_aux )
ldarg num
ldc.i4 1
clt
brfalse L1
ldc.i4 1
stloc num_aux
br L2
L1:
ldarg num
ldarg.0
ldarg num
ldc.i4 1
sub
callvirt instance int32 class Fac::ComputeFac (int32)
mul
stloc num_aux
L2:
ldloc num_aux
ret
}
}
Ceci est valable CIL programme qui peut être introduit dans un CIL assembleur comme ilasm.exe
pour créer un fichier exécutable. Comme vous pouvez le voir, CIL est entièrement humain, de lecture et d'écriture de la langue. Vous pouvez facilement créer valide CIL programmes dans tout éditeur de texte.
Vous pouvez aussi compiler le programme Java ci-dessus avec l' javac
compilateur, puis exécutez la classe résultante des fichiers par le biais de l' javap
"désassembleur" pour obtenir le suivant:
class Factorial extends java.lang.Object{
Factorial();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3; //class Fac
6: dup
7: invokespecial #4; //Method Fac."<init>":()V
10: bipush 10
12: invokevirtual #5; //Method Fac.ComputeFac:(I)I
15: invokevirtual #6; //Method java/io/PrintStream.println:(I)V
18: return
}
class Fac extends java.lang.Object{
Fac();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public int ComputeFac(int);
Code:
0: iload_1
1: iconst_1
2: if_icmpge 10
5: iconst_1
6: istore_2
7: goto 20
10: iload_1
11: aload_0
12: iload_1
13: iconst_1
14: isub
15: invokevirtual #2; //Method ComputeFac:(I)I
18: imul
19: istore_2
20: iload_2
21: ireturn
}
L' javap
de sortie n'est pas compilable (à ma connaissance), mais si on le compare à la CIL de sortie ci-dessus, vous pouvez voir que les deux sont très similaires.
Ils sont essentiellement de faire la même chose, MSIL est la version de Microsoft du bytecode Java.
Les principales différences à l'interne sont:
- Bytecode a été développé à la fois pour la compilation et l'interprétation, tout en MSIL a été développé expressément pour la compilation JIT
- MSIL a été développé pour prendre en charge plusieurs langages (C# et VB.NET, etc.) rapport du Bytecode en cours de rédaction pour juste Java, résultant en Bytecode être plus similaire à Java syntaxiquement qu'IL est spécifique .NET de la langue
- MSIL a plus explicites de la délimitation entre la valeur et les types référence
Beaucoup plus d'informations et une comparaison détaillée peut être trouvée dans cet article par K John Gough (document postscript)
Il n'y a pas beaucoup de différences. Les deux sont des formats intermédiaires du code que vous avez écrit. Lorsqu'il est exécuté, les machines Virtuelles qui exécutent le langage intermédiaire géré cela signifie que la Machine Virtuelle contrôle les variables et les appels. Il y a même une langue dont je ne me rappelle maintenant que peut courir .Net et Java de la même façon.
Bref, c'est juste un autre format pour la même chose
Edit: Trouvé le langage (en plus de la Scala): Il est FAN (http://www.fandev.org/), a l'air très intéressant, mais pas de temps encore à évaluer