tabla quién que maquina intérprete interprete extension estructura ejemplos cursos codigo java .net bytecode cil

quién - ¿Diferencias entre bytecode de MSIL y Java?



tabla de codigo bytecode (8)

Soy nuevo en .Net y estoy tratando de entender lo básico primero. ¿Cuál es la diferencia entre bytecode de MSIL y Java?


Básicamente están haciendo lo mismo, MSIL es la versión de Microsoft de bytecode de Java.

Las principales diferencias internas son:

  1. Bytecode fue desarrollado para compilación e interpretación, mientras que MSIL fue desarrollado explícitamente para compilación de JIT
  2. MSIL fue desarrollado para admitir múltiples idiomas (C # y VB.NET, etc.) en comparación con el código de bytes que se escribe solo para Java, lo que hace que Bytecode sea más similar a Java sintácticamente que IL a cualquier lenguaje .NET específico.
  3. MSIL tiene una delineación más explícita entre el valor y los tipos de referencia

Se puede encontrar mucha más información y una comparación detallada en este artículo de K John Gough (documento postdata)


CIL también conocido como MSIL está destinado a ser legible por humanos. El bytecode de Java no lo es.

Piense en bytecode Java como código de máquina para hardware que no existe (pero que las JVM emulan).

CIL se parece más al lenguaje ensamblador, a un paso del código de la máquina, al tiempo que sigue siendo legible por el ser humano.


Creo que MSIL no debería comparar con el bytecode de Java, sino con "la instrucción que comprende los códigos de byte de Java".

No hay nombre de bytecode de java desmontado. "Java Bytecode" debería ser un alias no oficial, ya que no puedo encontrar su nombre en el documento oficial. Desensamblador del archivo Java Class

Imprime código desensamblado, es decir, las instrucciones que comprenden los códigos de bytes de Java, para cada uno de los métodos en la clase. Estos están documentados en la especificación de máquina virtual de Java.

Tanto las "instrucciones de Java VM" como las "MSIL" se ensamblan en .NET bytecode y código Java, que no son legibles por humanos.


De acuerdo, las diferencias son lo suficientemente pequeñas como para principiantes. Si desea aprender .Net a partir de lo básico, le recomiendo consultar la Common Language Infrastructure y el Common Type System.


En primer lugar, permítanme decir que no creo que las diferencias sutiles entre bytecode de Java y MSIL sea algo que debería molestar a un desarrollador de .NET novato. Ambas tienen el mismo objetivo de definir una máquina de destino abstracta que es una capa por encima de la máquina física que se utiliza al final.

Los bytecode de MSIL y Java son muy similares, de hecho hay una herramienta llamada Grasshopper que traduce MSIL a bytecode de Java, formé parte del equipo de desarrollo de Grasshopper para poder compartir un poco de mi conocimiento (desvanecido). Tenga en cuenta que dejé de trabajar en esto cuando apareció .NET framework 2.0, por lo que algunas de estas cosas pueden no ser ciertas más (de ser así, dejen un comentario y lo corregiré).

  • .NET permite tipos definidos por el usuario que tienen semántica de valores como apposed a la semántica de referencia regular ( struct ).
  • .NET admite tipos sin firmar, esto hace que las instrucciones sean un poco más ricas.
  • Java incluye la especificación de excepción de métodos en bytecode. Aunque la especificación de la excepción generalmente solo es aplicada por el compilador, la JVM puede aplicarla si se utiliza un cargador de clases distinto del predeterminado.
  • Los genéricos .NET se expresan en IL, mientras que los genéricos de Java solo usan borrado de tipo .
  • Los atributos .NET no tienen equivalente en Java (¿esto sigue siendo cierto?).
  • Las enums .NET no son mucho más que envoltorios alrededor de tipos enteros, mientras que las enums Java son enums bastante completas (gracias a Internet Friend para comentar).
  • .NET tiene parámetros de out y ref .

Existen otras diferencias de idioma, pero la mayoría no se expresa en el nivel de código de bytes, por ejemplo, si la memoria sirve a las clases internas no static Java (que no existen en .NET) no son una función de bytecode, el compilador genera un argumento adicional al constructor de la clase interna y pasa el objeto externo. Lo mismo es cierto para las expresiones .NET lambda.


No hay muchas diferencias. Ambos son formatos intermedios del código que usted escribió. Cuando se ejecutan, las máquinas virtuales ejecutarán el lenguaje intermedio administrado, lo que significa que la máquina virtual controla las variables y las llamadas. Incluso hay un lenguaje que no recuerdo en este momento que pueda ejecutarse en .Net y Java de la misma manera.

Básicamente, es solo otro formato para lo mismo

Editar: Encontré el idioma (además de Scala): es FAN ( http://www.fandev.org/ ), parece muy interesante, pero aún no hay tiempo para evaluar



CIL (el nombre propio de MSIL) y bytecode de Java son más parecidos de lo que son. Sin embargo, hay algunas diferencias importantes:

1) CIL fue diseñado desde el principio para servir como un objetivo para múltiples idiomas. Como tal, es compatible con un sistema tipo mucho más rico que incluye tipos firmados y sin firmar, tipos de valores, punteros, propiedades, delegados, eventos, genéricos, un sistema de objetos con una sola raíz y más. CIL admite funciones no necesarias para los lenguajes iniciales de CLR (C # y VB.NET), como funciones globales y optimizaciones de llamadas de cola . En comparación, Java bytecode se diseñó como un objetivo para el lenguaje Java y refleja muchas de las restricciones encontradas en Java. Sería mucho más difícil escribir C o Scheme usando bytecode de Java.

2) CIL fue diseñado para integrarse fácilmente en bibliotecas nativas y código no administrado

3) Java bytecode fue diseñado para ser interpretado o compilado, mientras que CIL fue diseñado asumiendo solo la compilación de JIT. Dicho esto, la implementación inicial de Mono usó un intérprete en lugar de un JIT.

4) CIL se diseñó ( y se especificó ) para tener un lenguaje de ensamblaje legible y legible por humanos que se asigna directamente al formulario de código de bytes. Creo que el bytecode de Java era (como su nombre lo indica) destinado a ser solo legible por máquina. Por supuesto, el bytecode de Java se descompila con relativa facilidad en el Java original y, como se muestra a continuación, también se puede "desmontar".

Debo señalar que la JVM (la mayoría de ellos) está más optimizada que la CLR (cualquiera de ellos). Por lo tanto, el rendimiento sin procesar puede ser una razón para preferir orientar el bytecode de Java. Sin embargo, este es un detalle de implementación.

Algunas personas dicen que el bytecode de Java fue diseñado para ser multiplataforma, mientras que CIL fue diseñado para ser solo de Windows. Este no es el caso. Hay algunos ismos de "Windows" en el framework .NET pero no hay ninguno en CIL.

Como ejemplo del punto número 4) anterior, escribí hace poco un compilador Java de juguete a CIL. Si le das a este compilador el siguiente programa Java:

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

mi compilador escupirá el siguiente 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 } }

Este es un programa CIL válido que se puede alimentar a un ensamblador CIL como ilasm.exe para crear un ejecutable. Como puede ver, CIL es un lenguaje totalmente legible y legible por humanos. Puede crear fácilmente programas CIL válidos en cualquier editor de texto.

También puede compilar el programa Java anterior con el compilador javac y luego ejecutar los archivos de clase resultantes a través del "desensamblador" de javap para obtener lo siguiente:

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 }

El resultado de javap no es compilable (que yo sepa) pero si lo comparas con el resultado de CIL anterior, puedes ver que los dos son muy similares.