Различия между MSIL и Java байт-кодом?

Я новичок в .Net, и я сначала пытаюсь понять основы. В чем разница между байт-кодом MSIL и Java?

Ответ 1

Прежде всего позвольте мне сказать, что я не думаю, что тонкие различия между байт-кодом Java и MSIL - это то, что должно беспокоить начинающего разработчика .NET. Они оба служат той же цели, что и определение абстрактной целевой машины, которая является слоем над физической машиной, используемой в конце.

MSIL и байт-код Java очень похожи, на самом деле есть инструмент под названием Grasshopper, который переводит байт-код MSIL на Java, я был частью команда разработчиков для Grasshopper, чтобы я мог поделиться немного моих (выцветших) знаний. Обратите внимание, что я прекратил работать над этим, когда .NET framework 2.0 вышел, поэтому некоторые из этих вещей могут быть неверными (если это так, оставьте комментарий, и я исправлю его).

  • .NET позволяет определять типы пользователей, которые находятся в стеке (struct).
  • .NET поддерживает неподписанные типы, это делает инструкцию немного более богатой.
  • Java включает спецификацию исключений методов в байт-коде. Хотя спецификация исключения обычно применяется только компилятором, она может быть задействована JVM, если используется загрузчик классов, отличный от используемого по умолчанию.
  • Генераторы .NET выражаются в IL, в то время как Java generics используют тип erasure.
  • У атрибутов .NET нет эквивалента в Java (это все еще верно?).
  • .NET enums не намного больше, чем обертки вокруг целочисленных типов, тогда как Java enums - это в значительной степени полноценные классы (благодаря Internet Friend для комментариев).
  • У .NET есть параметры out и ref.

Существуют другие языковые различия, но большинство из них не выражаются на уровне байтового кода, например, если память обслуживает Java не static внутренние классы (которые не существуют в .NET) не являются функцией байт-кода, компилятор генерирует дополнительный аргумент для внутреннего конструктора классов и передает внешний объект. То же самое верно и для лямбда-выражений .NET.

Ответ 2

Они по сути делают то же самое, MSIL - это версия Java для байт-кода Java.

Основные различия внутри:

  • Bytecode был разработан как для компиляции, так и для интерпретации, в то время как MSIL был явно разработан для компиляции JIT
  • MSIL была разработана для поддержки нескольких языков (С# и VB.NET и т.д.) по сравнению с Bytecode, написанных только для Java, в результате чего Bytecode более похож на Java синтаксически, чем IL на любой конкретный язык .NET.
  • MSIL имеет более четкое разграничение между значениями и ссылочными типами

Более подробная информация и подробное сравнение можно найти в в этой статье K John Gough (документ postscript)

Ответ 3

CIL (собственное имя для MSIL) и байт-код Java более похожи друг на друга. Существуют некоторые важные отличия:

1) CIL был разработан с самого начала, чтобы служить в качестве цели для нескольких языков. Таким образом, он поддерживает гораздо более богатую систему типов, включая подписанные и неподписанные типы, типы значений, указатели, свойства, делегаты, события, генерики, объектную систему с одним корнем и многое другое. CIL поддерживает функции, не требуемые для начальных языков CLR (С# и VB.NET), таких как глобальные функции и оптимизация хвостовых вызовов. В сравнении, байт-код Java был разработан как цель для языка Java и отражает многие ограничения, обнаруженные в самой Java. Было бы намного сложнее написать C или Scheme с использованием байт-кода Java.

2) CIL был разработан, чтобы легко интегрировать в собственные библиотеки и неуправляемый код

3) Байт-код Java был разработан для интерпретации или компиляции, тогда как CIL был разработан с учетом компиляции JIT. Тем не менее, первоначальная реализация Mono использовала интерпретатор вместо JIT.

4) CIL был разработан (и указан), чтобы иметь форму для чтения и записи на языке человека, которая непосредственно отображается в форме байт-кода. Я считаю, что байт-код Java был (как следует из названия), предназначенным только для машинного чтения. Конечно, байт-код Java относительно легко декомпилируется обратно к исходной Java и, как показано ниже, его также можно "разобрать".

Следует отметить, что JVM (большинство из них) более оптимизирован, чем CLR (любой из них). Таким образом, необработанная производительность может стать поводом для предпочтения таргетинга на байт-код Java. Однако это детализация реализации.

Некоторые говорят, что байт-код Java был разработан как мультиплатформенный, тогда как CIL был разработан только для Windows. Это не тот случай. В среде .NET есть некоторые "Windows", но в CIL их нет.

В качестве примера пункта 4), выше, я написал игру Java Java для компилятора CIL некоторое время назад. Если вы кормите этот компилятор следующей программой 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 ;
    }
}

мой компилятор выплюнет следующий 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
   }
}

Это действительная программа CIL, которая может быть загружена в ассемблер CIL, например ilasm.exe, для создания исполняемого файла. Как вы можете видеть, CIL - полностью понятный и доступный для чтения язык. Вы можете легко создавать действительные программы CIL в любом текстовом редакторе.

Вы также можете скомпилировать Java-программу выше с помощью компилятора javac, а затем запустить результирующие файлы классов с помощью дизассемблера javap, чтобы получить следующее:

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
}

Вывод javap не компилируется (насколько мне известно), но если вы сравните его с выводом CIL выше, вы увидите, что эти два очень похожи.

Ответ 4

Не так много различий. Оба являются промежуточными форматами кода, который вы написали. При выполнении виртуальных машин будет выполняться управляемый промежуточный язык, что означает, что виртуальная машина управляет переменными и вызовами. Существует даже язык, который я не помню прямо сейчас, который может работать на .Net и Java таким же образом.

В основном, это просто другой формат для одной и той же вещи

Изменить: Нашел язык (кроме Scala): он FAN (http://www.fandev.org/) выглядит очень интересно, но нет времени но оценить

Ответ 5

CIL aka MSIL предназначен для чтения человеком. Java-байт-код не является.

Подумайте о том, что байт-код Java является машинным кодом для аппаратного обеспечения, которого нет (но какие JVM-эмуляции).

CIL больше похож на язык ассемблера - один шаг от машинного кода, хотя он все еще доступен для чтения.

Ответ 6

Согласовано, различия достаточно малы, чтобы проникнуть в качестве новичка. Если вы хотите изучить .Net, начиная с основ, я бы рекомендовал посмотреть инфраструктуру Common Language и систему Common Type.

Ответ 7

Серж Лидин создал приличную книгу о деталях MSIL: Expert.NET 2.0 IL Assembler. Я также смог быстро подобрать MSIL, посмотрев простые методы, используя .NET Reflector и Ildasm (Tutorial).

Понятия между байт-кодом MSIL и Java очень похожи.

Ответ 8

Я думаю, что MSIL не следует сравнивать с Java-байт-кодом, но "инструкция, которая содержит байт-коды Java".

Нет имени дизассемблированного java-байт-кода. "Java Bytecode" должен быть неофициальным псевдонимом, поскольку я не могу найти его имя в официальном документе. Разборщик файла Java Class говорит

Распечатывает дизассемблированный код, т.е. инструкции, которые составляют байт-коды Java, для каждого из методов в классе. Они описаны в спецификации виртуальной машины Java.

Оба "Java VM commands" и "MSIL" собраны в .NET байт-код и Java-код, которые не читаются человеком.