当前位置:  开发笔记 > 编程语言 > 正文

MSIL和Java字节码之间的区别?

如何解决《MSIL和Java字节码之间的区别?》经验,为你挑选了3个好方法。

我是.Net的新手,我想先了解基础知识.MSIL和Java字节码有什么区别?



1> Motti..:

首先请允许我说,我不认为Java字节码和MSIL之间的细微差别应该是新手.NET开发人员的烦恼.它们都用于定义抽象目标机器的相同目的,该机器是最终使用的物理机器之上的层.

MSIL和Java字节码非常相似,实际上有一个名为Grasshopper的工具可以将MSIL转换为Java字节码,我是Grasshopper开发团队的一员,因此我可以分享一些我的(褪色)知识.请注意,当.NET framework 2.0问世时,我已经停止了这方面的工作,因此其中一些事情可能不再适用(如果是这样,请发表评论,我会更正).

.NET允许用户定义的类型具有与常规引用语义(struct)相关的值语义.

.NET支持无符号类型,这使得指令集更加丰富.

Java包含字节码中方法的异常规范.虽然异常规范通常仅由编译器强制执行,但如果使用非默认类加载器,则JVM可以强制执行异常规范.

.NET泛型用IL表示,而Java泛型仅使用类型擦除.

.NET属性在Java中没有等价物(这仍然是真的吗?).

.NET enums不仅仅是整数类型的包装器,而Javaenums几乎是完全成熟的类(感谢Internet Friend的评论).

.NET有outref参数.

还有其他语言差异,但大部分都没有在字节代码级别表达,例如,如果内存服务于Java的非static内部类(.NET中不存在)不是字节码功能,则编译器会生成一个额外的参数内部类的构造函数并传递外部对象..NET lambda表达式也是如此.



2> Guy Starbuck..:

它们本质上是做同样的事情,MSIL是微软的Java字节码版本.

内部的主要区别是:

    字节码是为编译和解释而开发的,而MSIL则是为JIT编译而开发的

    MSIL的开发是为了支持多种语言(C#和VB.NET等)而不是只为Java编写的Bytecode,导致Bytecode在语法上比任何特定的.NET语言更类似于Java.

    MSIL在值和引用类型之间有更明确的描述

K John Gough在本文中可以找到更多的信息和详细的比较(后记文件)



3> Justin..:

CIL(MSIL的正确名称)和Java字节码比它们不同的更相同.但是有一些重要的区别:

1)CIL从一开始就被设计为多语言的目标.因此,它支持更丰富的类型系统,包括有符号和无符号类型,值类型,指针,属性,委托,事件,泛型,具有单个根的对象系统等.CIL支持初始CLR语言(C#和VB.NET)不需要的功能,例如全局函数和尾调用优化.相比之下,Java字节码被设计为Java语言的目标,并反映了Java本身的许多约束.使用Java字节码编写C或Scheme会困难得多.

2)CIL旨在轻松集成到本机库和非托管代码中

3)Java字节码被设计为解释或编译,而CIL的设计仅假设JIT编译.也就是说,Mono的初始实现使用了解释器而不是JIT.

4)CIL被设计(并指定)为具有人类可读和可写的汇编语言形式,其直接映射到字节码形式.我相信Java字节码(顾名思义)只是机器可读的.当然,Java字节码相对容易反编译回原始Java,如下所示,它也可以"反汇编".

我应该注意到JVM(大多数)比CLR(其中任何一个)都更加优化.因此,原始性能可能是更喜欢使用Java字节码的原因.这是一个实现细节.

有人说Java字节码设计为多平台,而CIL只设计为Windows.不是这种情况..NET框架中有一些"Windows"主义,但CIL中没有.

作为上面第4点的一个例子,我曾经写过一个玩具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程序.

您还可以使用编译javac器编译上面的Java程序,然后通过javap"反汇编程序" 运行生成的类文件以获取以下内容:

class Factorial extends java.lang.Object{
Factorial();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()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."":()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."":()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输出上面可以看到两个非常相似.


事实证明,已经尝试创建人类可读/可写的Java汇编语言.我找到的两个是[Jasmin](http://jasmin.sourceforge.net/)和[Java Bytecode Assembler](http://tinf2.vub.ac.be/~dvermeir/courses/compilers/javaa/)
我在这里写了一个更好的.与Jasmin不同,它旨在能够反汇编和重新组合任何有效的类文件.https://github.com/Storyyeller/Krakatau.我认为微软提供标准汇编程序而Java程序员必须自己编写汇编程序会更准确.
推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有