Différences entre MSIL et Java bytecode?

je suis nouveau à .Net et j'essaie de comprendre les bases d'abord. Quelle est la différence entre MSIL et Java bytecode?

73
demandé sur Motti 2008-09-18 22:13:34

8 réponses

tout d'abord, permettez-moi de dire que je ne pense pas que les différences subtiles entre Java bytecode et MSIL est quelque chose qui devrait déranger un développeur novice .NET. Ils ont tous deux le même but de définir une machine cible abstraite qui est une couche au-dessus de la machine physique utilisée à la fin.

MSIL et Java bytecode sont très similaires, en fait il ya un outil appelé Grasshopper qui traduit MSIL en Java bytecode, je faisais partie de l'équipe de développement de Grasshopper pour que je puisse partager un peu de mes connaissances (fanées). S'il vous plaît noter que j'ai cessé de travailler sur ce sujet autour quand .net framework 2.0 est sorti de sorte que certaines de ces choses peuvent ne pas être vrai plus (si donc s'il vous plaît laisser un commentaire et je vais le corriger).

  • . Net permet les types définis par l'utilisateur qui ont une sémantique de valeur telle qu'appliquée à la régulière sémantique de référence ( struct ).
  • .NET prend en charge les types non signés, ce qui rend l'ensemble d'instruction Un peu plus riche.
  • Java comprend la spécification d'exception de méthodes dans le bytecode. Bien que la spécification d'exception ne soit généralement appliquée que par le compilateur, elle peut l'être par le JVM si un chargeur de classe autre que celui par défaut est utilisé.
  • . les génériques Net sont exprimés en IL alors que les génériques Java n'utilisent que type erasure .
  • .NET les attributs N'ont pas D'équivalent en Java (est-ce encore vrai?).
  • .NET enums ne sont pas beaucoup plus que des enveloppements autour de types entiers tandis que Java enums sont à peu près des classes à part entière (merci à ami Internet pour les commentaires).
  • .NET a les paramètres out et ref .

il existe d'autres différences linguistiques, mais la plupart des ils ne sont pas exprimés au niveau du code octet, par exemple si la mémoire sert les classes internes Non- static de Java (qui n'existent pas dans .NET) ne sont pas une fonctionnalité de bytecode, le compilateur génère un argument supplémentaire au constructeur de la classe interne et passe l'objet externe. Il en va de même pour les expressions .net lambda.

69
répondu Motti 2018-01-14 18:28:41

ils font essentiellement la même chose, MSIL est la version de Microsoft de Java bytecode.

les principales différences internes sont:

  1. 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
  2. MSIL a été développé pour prendre en charge plusieurs langues (C# et VB.NET, etc.) versus Bytecode étant écrit pour juste Java, résultant en Bytecode étant plus similaire à Java syntaxiquement QU'IL ne l'est à N'importe quel langage spécifique."
  3. 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 peuvent être trouvées dans cet article de K John Gough (postscript document)

21
répondu Guy Starbuck 2013-06-26 14:11:09

CIL (le nom propre de MSIL) et Java bytecode sont plus les mêmes qu'ils sont différents. Il y a cependant quelques différences importantes:

1) CIL a été conçu dès le début pour servir de cible pour plusieurs langues. En tant que tel, il soutient un système de type beaucoup plus riche comprenant des types signés et non signés, des types de valeur, des pointeurs, des propriétés, des délégués, des événements, des génériques, un objet-système avec une racine simple, et plus encore. CIL qui prend en charge caractéristiques non requises pour les langues CLR initiales (C# et VB.NET) tels que global functions et tail-call optimizations . En comparaison, Java bytecode a été conçu comme une cible pour le langage Java et reflète bon nombre des contraintes rencontrées dans Java lui-même. Il serait beaucoup plus difficile d'écrire C ou Scheme en utilisant Java bytecode.

2) CIL a été conçu pour s'intégrer facilement dans les bibliothèques natives et le code non géré

3) Java bytecode a été conçu pour être interprété ou compilé tandis que CIL a été conçu en supposant la compilation JIT seulement. Cela dit, la mise en œuvre initiale de Mono a utilisé un interprète au lieu d'un JIT.

4 ) CIL a été conçu ( et spécifié ) pour avoir une forme de langage d'assemblage lisible et inscriptible qui correspond directement à la forme de bytecode. Je crois que Java bytecode était (comme son nom l'indique) destiné à être seulement une machine lisible. Bien sûr, le bytecode Java est relativement facilement décomposé vers le Java original et, comme montré ci-dessous, il peut également être"démonté".

je dois noter que la JVM (la plupart d'entre eux) est plus optimisée que le CLR (l'un d'entre eux). Ainsi, la performance brute pourrait être une raison de préférer cibler Java bytecode. C'est un détail d'implémentation.

certaines personnes disent que le bytecode Java a été conçu pour être multi-plateforme alors que CIL était conçu uniquement pour les fenêtres. Ce n'est pas le cas. Il y a quelques "fenêtres"isms dans le framework .NET mais il n'y en a pas dans CIL.

comme exemple du point 4) ci-dessus, j'ai écrit un toy Java to cil compiler a while back. Si vous donnez à ce compilateur le programme Java suivant:

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 crachera le CIL suivant:

.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
   }
}

c'est un programme CIL valide qui peut être introduit dans un assembleur CIL comme ilasm.exe pour créer un exécutable. Comme vous pouvez le voir, CIL est un langage lisible et accessible en écriture. Vous pouvez facilement créer des programmes CIL valides dans n'importe quel éditeur de texte.

vous pouvez également compiler le programme Java ci-dessus avec le compilateur javac et ensuite exécuter les fichiers de classe résultants à travers le javap "démonter" pour obtenir ce qui suit:

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
}

la sortie javap n'est pas compilable (à ma connaissance) mais si vous comparez-le à la sortie CIL ci-dessus vous pouvez voir que les deux sont très similaires.

20
répondu Justin 2012-02-06 03:15:52

CIL alias MSIL is intended to be human-readable. Java bytecode ne l'est pas.

pense à Java bytecode comme étant du code machine pour du matériel qui n'existe pas (mais que JVM émule).

CIL est plus comme un langage d'assemblage - un pas à partir du code machine, tout en étant lisible par l'humain.

2
répondu slim 2008-09-18 18:18:00

Il n'y a pas beaucoup de différences. Les deux sont des formats intermédiaires du code que vous avez écrit. Une fois exécutées, les machines virtuelles exécuteront le langage intermédiaire géré, ce qui signifie que la Machine virtuelle contrôle les variables et les appels. Il y a même un langage dont je ne me souviens pas en ce moment qui peut fonctionner à .Net et Java de la même façon.

Bref, c'est juste un autre format pour la même chose

Edit: a trouvé la langue (d'ailleurs Scala): IT's FAN ( http://www.fandev.org / ), semble très intéressant, mais pas encore le temps d'évaluer

2
répondu GHad 2008-09-18 18:32:46

D'accord, les différences sont assez minute pour ingérer en tant que débutant. Si vous voulez apprendre le.net à partir de l'essentiel, je vous recommande vivement de vous intéresser à l'Infrastructure linguistique commune et au système de caractères communs.

1
répondu Internet Friend 2008-09-18 18:22:27

Serge Lidin a écrit un livre décent sur les détails de MSIL: Expert .NET 2.0 Il Assembler . J'ai également été capable de prendre MSIL rapidement en regardant des méthodes simples en utilisant réflecteur .net et Ildasm (Tutorial) .

les concepts entre MSIL et Java bytecode sont très similaires.

1
répondu Jeffrey LeCours 2008-09-18 18:23:36

je pense que MSIL ne devrait pas comparer avec Java bytecode, mais"l'instruction qui comprend les Java bytecodes".

il n'y a pas de nom du bytecode java démonté. "Java Bytecode" devrait être un alias non officiel, car je ne trouve pas son nom dans le document officiel. Le Fichier de Classe Java Désassembleur dire

imprime le code démonté, c.-à-d. les instructions qui comprennent les bytecodes Java, pour chacun des les méthodes de la classe. Ceux-ci sont documentés dans la spécification de la machine virtuelle Java.

les deux "Java VM instructions" et "MSIL" sont assemblés en .net bytecode et Code Java, qui ne sont pas lisibles par l'homme.

1
répondu Dennis C 2008-11-30 11:35:23